
개발을 하던 중
React Hook useEffect has a missing dependency: 'fetchMovieData'. Either include it or remove the dependency array.이라는 에러를 마주하게 되었다.
useEffect를 사용하면서 누락된 종속성이 있기 때문에 발생하는 에러인데, 처음 리액트를 쓰다보면 자주 마주칠 수 있는 에러이므로 에러해결을 공유하기위해 글을 작성했다.
const [nickname, setNickname] = useState<string>("");
const [cookies] = useCookies(["accessToken"]);
useEffect(() => {
getInfo();
},[]);
const getInfo = async() => {
try{
const response = await axios.get(`받아올 API`,{
headers : {
Authorization : `Bearer ${cookies.accessToken}`,
},
});
setNickname(response?.이하 코드);
}catch(error){
if(error instanceof AxiosError) {
console.log(error);
}
}
};
accessToken을 포함한 get요청을 받아 데이터에 있는 닉네임 값을 세팅하는 코드이다. getInfo()를 실행하여 값을 배치하면 되겠다고 했는데 getInfo()에서 useState값을 참조하여 의존성에 영향을 준다는 것을 알았다.내가 찾은 해결방법은 아래와 같다.
eslint-disable-next-line react-hooks/exhaustive-depsuseEffect()로 로직을 옮겨서 관리하기useCallback()을 사용하여 해결하기먼저 1번을 사용하는 방법은 문제가 되는 위치에 저 코드를 삽입하는 것이다.
useEffect(() => {
getInfo();
// eslint-disable-next-line react-hooks/exhaustive-deps
},[]);
그러나 이 방법은 일시적으로 에러를 안보이게 감추는 행위이기 때문에 근본적인 문제를 해결해야한다.
useEffect는 구성 요소를 외부 시스템과 동기화할 수 있게 만들어주는 리액트 훅이다.
const [nickname, setNickname] = useState<string>("");
const [cookies] = useCookies(["accessToken"]);
useEffect(() => {
const getInfo = async () => {
await axios
.get(`${api.user}/info`, {
headers: {
Authorization: `Bearer ${cookies.accessToken}`,
},
})
.then((response) => setNickname(response?.data.data.nickname));
};
getInfo();
}, [cookies]);
이 방법을 사용하는 것도 괜찮은 방법이라고 생각한다.
그러나, 다른곳에서 getInfo()함수를 사용할 수 없고 코드가 길어짐에 따라 의존성 배열에 더 많은 값이 들어가 가독성이 떨어지게 된다.
useCallback(fn, dependencies)은 재렌더링 사이에 함수 정의를 캐시할 수 있는 리액트 훅이다.
fn은 캐시하려는 함수의 값으로, 모든 인수를 가지고 모든 값을 반환할 수 있다. useCallback을 사용하지 않으면 리렌더링마다 함수를 만들고 새롭게 실행되는 데, 사용 시에는 dependencies값이 변화할 때만 함수가 실행되어 불필요하게 함수가 생성되고 실행하는 것을 막을 수 있다. useEffect내부에 모든 로직을 담는 것이 아니라 로직을 분리하기 때문에 유지보수 관점에서도 useCallback을 사용하는 편이 더 좋다고 느껴진다. const [nickname, setNickname] = useState<string>("");
const [cookies] = useCookies(["accessToken"]);
const getInfo = useCallback(async () => {
try {
const response = await axios.get(`${api.user}/info`, {
headers: {
Authorization: `Bearer ${cookies.accessToken}`,
},
});
setNickname(response?.data.data.nickname);
} catch (error) {
if (error instanceof AxiosError) {
console.log(error);
}
}
}, [cookies.accessToken]);
useEffect(() => {
getInfo();
}, [getInfo]);