ohah/react18-study

리액트 훅에 대한 질문입니다.

Closed this issue · 1 comments

강사님 안녕하세요. 리액트 훅에 대한 질문입니다.

리액트는 최상위 레벨에서 즉, 반복문 조건문 혹은 중첩된 함수가 아닌 컴포넌트 내부 또는 Custom Hook에서만 Hook을 호출해야한다고 하는데요. 제가 공식문서를 읽어 봤지만 이해가 잘되지 않아서 질문드립니다. 제가 이해한 내용은 다음과 같습니다.

우선 조건문 내에서 Hook을 호출한다고 가정하고 말씀드리면 리액트의 Hook이 호출되는 순서에 의존하기 때문에 조건문의 결과가 바뀌면서 Hook의 호출 순서가 달라지면 호출 되는 Hook의 순서가 하나씩 밀리면서 버그를 발생시키기 때문에 Hook을 컴포넌트의 최상위에서만 호출하라고 이해하였습니다.

function App() {
  const [count, setCount] = useState(0);
  
  if(count <= 3) {
    useEffect(() => {
      console.log('count가 3이하입니다.');
      console.log(count);
    })
  }

  useEffect(()=> {
    console.log(count);
  })
}

위에서는 무조건 버그가 일어난다는 식으로 말하고 있지만 제가 생각할 때는 예시코드처럼 작성하면 컴포넌트의 최상위에서 상태 값들이 의존하지 않는 즉, 상태값들을 변경하지 않는 Hook들의 순서가 바뀌는건 순서가 하나씩 밀려도 상관이 없다고 생각이 들어서 버그를 발생시키지 않을거 같은데요. 제가 이해한 것과 생각한 것이 맞을까요?

참고

ohah commented

리액트는 함수형 컴포넌트가 실행되어서 리액트내의 라이프싸이클에 따라 렌더링 되면서, useEffect라는 함수는 무조건 같이 실행이 됩니다.

그리고 라이프싸이클에 따라 특정 조건에 따라 다시 실행되기도 합니다.
사용자가 해당 컴포넌트 안에 useEffect(()=>{...},[]) 형태로 값을 집어 넣으면 해당 함수를 같이 포함시켜 실행하게 되는 구조입니다
리액트는 최적화를 위해 한번 렌더링이 되면 React.memo를 활용한것처럼 해당 훅 부분도 메모제이션(등록) 됩니다.
뎁쓰나, useState, 상태관리툴, 라우터 등의 특정 조건에 따라 훅함수는 재실행되거나, 갱신이 되는데
훅 함수 등록 자체에 특정 조건이 있게 되면 훅에 등록되는 함수가 어떨때는 1개, 어떨때는 2개가 되어버립니다.
메모제이션 된 함수의 개수 자체가 차이가 나는 렌더링 상황이 온다면, 리액트에선 에러를 뿜습니다.
훅의 메모제이션(등록)의 경우 최적화를 위한것이기 때문에, 메모제이션 된 함수의 개수가 바뀌거나 동작이 바뀌면 안되는 과정 중 하나입니다.
그런데 위처럼 조건에 따라 훅 함수의 등록 개수가 차이가 나게 되면 훅을 감싸고 있는 조건문에 따라 결과적으로는 최적화 과정에 의해 결과값이 바뀌는 의도하지 않은 현상이 일어납니다.

말씀하신 예제코드처럼 등록한 useEffect내에서 특정한 이벤트가 일어나지 않는다면 버그가 발생할일은 없지만
굳이 그런 용도로 useEffect를 사용 할 경우 useEffect의 훅을 사용할 의미가 없는 경우가 많고
위의처럼 작성한 코드가 다른 의존하는 컴포넌트의 상태값에 값이 변경되거나 하는 등 훅이 재호출되는 경우 해당 컴포넌트에서 문제가 없을지라도 오동작 될 수도 있구요

즉 요약하자면 단일 컴포넌트의 코드로써 자체는 버그 발생이 없긴 하지만,
특정 일부 상황에서나 문제가 없는 코드이고,
대부분의 상황에서는 useEffect의 설계 목적이나, 구조, 그리고 사용방법을 고려하면 강력히 피해야 할 코드로 안내하고 있다고 보시면 될 것 같습니다.