[React] useEffect 내부에서 setState 사용하기

hyeondoonge·2021년 4월 19일
1

React 정복하기

목록 보기
4/5
post-thumbnail

useEffect를 사용할 때, 최적화를 위해 두 번째 인자로 의존성 배열을 줄 수가 있다.
이를 주지 않으면 렌더링 할 때 마다 실행하겠다는 얘긴데, 의존성 배열을 주게 되면 배열안에 있는 변수가 변경되는 경우에만 useEffect를 실행해서 조건부 effect 수행이 가능하게 된다.

앞서 업로드된 [React] useEffect와 useRef 활용하기로 이전문제는 해결했지만, useEffect의 의존성배열을 사용하던 중에 문제가 생겼고 해결법을 작성해보려한다.

const [isLoaded, setIsLoaded] = useState(false);
const [problem, setProblem] = useState({});

...

  useEffect(async () => {
    if (isLoaded) {
      ...
      setDescription(problem.description);
    } else { // 마운트 된 직후 else문을 실행
      const fetchedProblem = await fetch(`...`);
      setIsLoaded(true);
      setProblem(fetchedProblem);
    }
  }, [isLoaded, problem]);

현재 의존성 배열에 2개의 값이 있다.
react문서에 따르면, effect는 의존성 중 하나가 변경되면 항상 재생성된다.

set은 비동기적으로 한 번에 처리되니까 setIsLoaded랑 setProblem도 일괄적으로 처리될것이다라고 예상했지만,
setProblem이 무시되었다.

의존성 배열 원소 중 하나인 isLoaded의 변경이 일어났기 때문에 effect가 재생성된다.
따라서 다음 구문의 setProblem은 무시되게된다.

  useEffect(async () => {
    if (isLoaded) {
      setHashtags(problem.categories);
    } else {
      const fetchedProblem = await fetch(`...`);
      setIsLoaded(true);
      setProblem(fetchedProblem);
    }
  }, [problem]);

이를 해결하기 위해 useEffect를 problem이 변경될 때 실행하도록 코드를 변경했다.
위같이 변경을 하고나서 setIsLoaded 후에 setProblem이 정상적으로 실행이 되는 것을 볼 수 있다.

전혀 의존성배열을 선언하는데 문제가 있을 거라 예상못했는데,,
리액트 문서를 통해 속시원하게 해결했다. 🥳

0개의 댓글