개발 기록 남기기✍️

[React] Custom Hook - 초기 렌더링 때 useEffect 실행 막기 본문

Front-End/React

[React] Custom Hook - 초기 렌더링 때 useEffect 실행 막기

너해동물원 2023. 3. 14. 19:41

🤷🏻‍♀️ 문제 상황

우닫탕타앝앙
문제의 코드

 

React와 REST API를 활용하여 지난 과제 때 바닐라 JS로 만들었던 투두리스트를 다시 만들고 있는 중이다.

useEffect를 사용하여 todoItem의 done 속성이 바뀔 때마다 useEffect를 실행하고 API 통신을 하도록 코드를 작성했다.

 

근데 useEffect의 특성 상, 컴포넌트가 처음 렌더링 될 때 state가 세팅되므로 state가 변화되었다고 감지해 종속 배열에 상관없이 초기 렌더링 때 useEffect가 항상 실행된다.

그래서 초기 렌더링 떄 useEffect가 실행되고, 수정할 todoItem이 세팅되지 않은 상태이기 때문에 API 요청에 빈 데이터가 들어가게 되고, 이로 인해 Network Error가 발생하게 되었다.

 

 

💻 해결책 - useRef를 활용한 Custom hook

이 문제를 해결하기 위해 useRef를 사용해서 컴포넌트가 마운트되었는지 여부를 추적했다.

컴포넌트 최상단에 const isMounted = useRef(false)를 선언해주고, useEffect 안에서 if문을 활용하여 isMounted가 true일 때만 API 요청 함수를 실행하고, false일 때는 isMounted를 true로 변경시켜주었다.

function TodoItem({ todo }) {
  ...
  const isMounted = useRef(false);
	
  ...
  const handleChangeDone = async (todo) => {
	setIsDone(!isDone);
	setTodoItem({ ...todo, done: !isDone });\
  };

  const setPostsByResponse = async () => {
	await editTodoAPI(todoItem);
	const data = await getTodosAPI();
	setTodoList([...data]);
  };

  useEffect(() => {
    if(isMounted.current) {
      setPostsByResponse()
    } else {
      isMounted.current = true;
    }
  }, [isDone]);

	...
}

초기 렌더링 시 useEffect가 실행되면 useEffect는 isMounted의 값만 바꾸고 끝난다. 이후에 isDone의 상태가 변경될 떄마다 useEffect가 실행되고, setPostsByResponse 함수가 실행되게 된다.

 

이 부분을 custom hook으로 만들어서 다른 파일로 뺄 수 있을 것 같다.

// useDidMountEffect.jsx
import { useRef, useEffect } from "react";

export const useDidMountEffect = (func, deps) => {
  const isMounted = useRef(false);

  useEffect(() => {
    if (isMounted.current) func();
    else isMounted.current = true;
  }, deps);
};
// 코드에 적용
import { useDidMountEffect } from '../../../utils/useDidMountEffect';

function TodoItem({ todo }) {
  ...

  const setPostsByResponse = async () => {
    await editTodoAPI(todoItem);
    const data = await getTodosAPI();
    setTodoList([...data]);
  };

  useDidMountEffect(setPostsByResponse, [isDone]);
  
  ...
}

코드가 훨씬 깔끔해진 걸 볼 수 있다.

 

잘 작동한다~!


useRef를 어떻게 사용해야할 지 감이 안 잡혔는데, 해당 hook을 만들어보니까 대충 어떻게 써야할 지 이제는 좀 알 것 같다. (진짜 대충...)

 

'Front-End > React' 카테고리의 다른 글

[React] React Hooks, useState란 무엇인가  (0) 2023.03.19
[React] useEffect란 무엇인가  (0) 2023.03.16
[React] useReducer란 무엇인가  (0) 2023.03.13
[React] Context API란 무엇인가  (0) 2023.03.10
[React] useRef란 무엇인가  (0) 2023.03.07