setState의 동기(?)처리

준영·2022년 11월 5일
0

문제발생 )

문제가 발생한 이유를 간단하게 말하자면, 버튼을 클릭하면 searchFlag라는 값이 true로 바뀌고, 그 바뀐 값으로 apiLoad()라는 함수에서 분기를 태워 결과가 달라지는 과정을 거친다.

하지만 버튼을 눌렀음에도 불구하고 searchFlag가 false일 때, 처리되는 결과가 발생하는 문제가 발생하여 콘솔을 찍어봤다.

  const [searchFlag, setSearchFlag] = useState(false);

  // 헤더 검색 클릭 시, api 호출 함수
  const searchClick = () => {
    console.log("검색 버튼 클릭");
    console.log("검색 키워드", inputValue);
    // 검색 유무 판단 true on
    setSearchFlag(true);
    console.log("검색 유무", searchFlag);
    // api 호출 완료 전 까지 로딩창을 보여주기 위한 true
    setLoadingState(true);
    // api 호출 함수 (searchState로 일반 호출, 검색 호출 분기가 나뉘어짐)
    apiLoad();
  };

문제원인 )

useState는 비동기로 동작하는데, 정확히는 setState함수가 비동기로 동작한다.

동기(Synchronous) – 순서대로 하나씩 처리.
비동기(Asynchronous) – 순서가 아닌 이벤트에 따라 처리.

그렇다면 setState는 왜 비동기로 작동하는걸까?

state는 값이 변경되면 리렌더링이 발생하는데, 변경이 하나라면 리렌더링이 한번만 발생하지만 수십 개, 수백 개의 값이 계속 변경된다면 속도적인 부분에서도 별로이고, 매번 렌더링만 할 것이다.

따라서 변경된 값들을 모아 한번에 업데이트를 진행하여 렌더링을 줄이고자 배치(Batch) 기능을 사용해 비동기로 작동한다고 볼 수 있다.

문제해결 )

let으로 state를 선언하고, setState를 이용하여 값을 변경하지 않았다.

  let [searchFlag, setSearchFlag] = useState(false);
  
    // 헤더 검색 클릭 시, api 호출 함수
  const searchClick = () => {
    console.log("검색 버튼 클릭");
    console.log("검색 키워드", inputValue);
    // 검색 유무 판단 true on
    searchFlag = true;
    console.log("검색 유무", searchFlag);
    // api 호출 완료 전 까지 로딩창을 보여주기 위한 true
    setLoadingState(true);
    // api 호출 함수 (searchState로 일반 호출, 검색 호출 분기가 나뉘어짐)
    apiLoad();
  };

근데 아무리 생각해도, 이거 말고 더 좋은 방법이 있는거 같은데 (useEffect에 의존성 배열을 사용한다거나, setState 함수에 인자로 함수를 넣어 주는것) 어떻게 사용 할지 잘 모르겠다. 이 부분은 좀더 고민한 다음에 수정을 해야 할 것 같다.

ps. 나중에 나는, flag값을 굳이 state로 선언을 안해도 되는 것을 알았다. (리렌더링이 필요없으니까...)

profile
개인 이력, 포폴 관리 및 기술 블로그 사이트 👉 https://aimzero-web.vercel.app/

0개의 댓글