[TIL] React, React Hook "" is called conditionally. 문제 해결!

최현석·2021년 8월 11일
5

8월의 배움

목록 보기
3/3

개발 중에 마주친 에러!

React Hook "useMemo" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?

다음과 같은 에러는 useMemo 뿐만 아니라 useEffect 등 hooks를 사용할 때도 동일하게 적용된다.

해당 에러가 뜨는 이유는

Hook이 조건부로 선언되었기 때문이다.

1. 어? 그런데 나 조건부 설정한 거 없는데??

2. 그럼 Hook 안에 조건문을 못쓰나?

난 이렇게 두가지의 내적 외침이 있었다.

그래서 코드를 보며,

내부에 선언된 조건문이 문제일리는 없는데,, 흠..

하며 전에 짰던 코드를 뒤적거렸다.

역시 내부 조건문이 문제일리는 없었다.

그렇다면 어떤 이유에서 해당 에러가 발생했을까?

함수 실행 중, Hook 선언 전에 조건을 통해 먼저 return(종료) 되면 안된다.

const Container = () =>{
	const { data, error } = useSelector((state) => state.accounts.accounts);
	...
    if(error){
    return(
    	<ERR>에러가 발생했습니다.</ERR>
    )
    
    const TableRenderer = useMemo(()=>{<Table/>},[]);
    
    return (
    	{TableRenderer}
    )
    }
}

내 코드는 위와 같은 상황이었다.

위와 같은 상황에서는 에러가 발생한다.

hook이 선언되기 전에

조건절로 Container의 return이 발생하기 때문이다.

Did you accidentally call a React Hook after an early return?

에러 메시지에서도 친절히 안내 해준다.

위 코드는 아래와 같이 바꿔줘야 한다.

const Container = () =>{

	const { data, error } = useSelector((state) => state.accounts.accounts);
	...
     const TableRenderer = useMemo(()=>{<Table/>},[]);
    ...
    
    if(error){
    return(
    	<ERR>에러가 발생했습니다.</ERR>
    )
    
   
    return (
    	{TableRenderer}
    )
    }
}

리액트 Hook의 2원칙

1. Hook 은 최상위에서만 선언되어야 한다.

반복문, 조건문 혹은 중첩된 함수 내에서 훅을 호출하면 안된다.

리액트는 Hook이 호출되는 순서에 의존하기 때문에 Hook의 실행순서가 밀리게 되거나 건너뛰면 버그를 야기한다.

만약 조건부로 Hook을 쓰고 싶다면 Hook 내부에 선언해야 한다.

2. 오직 React 함수 내에서만 Hook을 호출해야 한다.

훅을 일반적인 자바스크립트 함수에서 호출하면 안된다.

대신 리액트 함수 컴포넌트나 커스텀 훅에서는 호출이 가능하다.

출처

profile
노력과 성장을 기록합니다.

0개의 댓글