문제가 발생한 이유를 간단하게 말하자면, 버튼을 클릭하면 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) – 순서가 아닌 이벤트에 따라 처리.
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로 선언을 안해도 되는 것을 알았다. (리렌더링이 필요없으니까...)