[Crocs Clone] Hook은 무조건 한번은 실행되야 한다.

Jihyun-Jeon·2022년 7월 11일
0

React

목록 보기
15/26

https://stackoverflow.com/questions/54938236/can-you-early-return-with-react-hooks
https://ko.reactjs.org/docs/hooks-rules.html

✅ 요약

React에서 hook은 조건부 렌더링 되거나, hook이 읽히기 전에 early return되면 안된다!


👩🏻‍💻 구상

로그인 성공시 toastMessage 값이 바뀌면 Toast 컴포넌트가 리렌더링 된다.
이때 toastMessage의 배열에 값이 없으면 Toast 컴포넌트를 리턴하여 끝내고,
배열에 값이 있다면 jsx가 렌더된다.
이후 1초 뒤에 toastMessage배열에 값을 없애주어 toast 팝업창이 사라지게 한다.

🔆 문제

📍 문제 코드 <Toast.js>

useEffect를 실행하기 전에 if문이 실행된다면, 아래있는 hook은 실행이 안됨.
그러나, hook은 최소 한번은 실행되야 하기때문에 이 코드는 오류가 남.

const Toast = ({ toastMessage, setToastMessage }) => {
  // 1. 조건문 먼저 실행되면 컴포넌트가 종료되서, 아래있는 useEffect hook이 안읽히는 경우가 있게됨.
  if (toastMessage.length < 1) {
    return null;
  }

  // 2. hook은 : 무조건 한번은 실행되야 된다. 따라서 (if문 앞쪽에 쓰는것이 올바름.)
  useEffect(() => {
    if (toastMessage.length > 0) {
      setTimeout(() => {
        setToastMessage([]);
      }, 1000);
    }
  }, [toastMessage]);

🔆 과정

📍 해결 코드

  • if문을 hook코드 밑으로 써줌
  • 코드 실행순서 : useEffect함수 자체가 읽힌 후 > if문 > jsx > useEffect함수 내부의 콜백함수 읽힘
const Toast = ({ toastMessage, setToastMessage }) => {

  // 1. hook은 : 무조건 한번은 실행되야 된다. 따라서 if문을 hook코드 밑에 써줌
  useEffect(() => {
    if (toastMessage.length > 0) {
      setTimeout(() => {
        setToastMessage([]);
      }, 1000);
    }
  }, [toastMessage]);

  // 2. 어떤 컴포넌트가 조건부로 나오고 안나오고 할때, 이런식으로 컴포넌트 안에서 return을 해줘버림
  if (toastMessage.length < 1) {
    return null;
  }

  return (
    <div className="toast">
      <p className="imoji">🙂</p>
      {toastMessage.join()}
    </div>
  );
};

🔆 결론 - Hook은 반복문, 조건문, 중첩된 함수 내에서 Hook을 실행하지 말기!

  • Hook은 무조건 한번은 실행해야 하기 때문에, 조건문 안에서 실행되면 안된다.
  • Hook은 "최상위 컨텍스트"에서 실행되야 하므로, 컴포넌트 함수 컨텍스트 안에 있어야 되고, 다른 블록 안에 있으면 안된다.
    → 따라서 반복문, 조건문, 중첩된 함수 내에서 Hook을 실행하지 마세요. (위코드 자료 참조)
import React, { useState } from "react"

function Hooks(props) {
  if (!props.isExist) {
    const [state, setState] = useState(); // Error!
  }

  const [state2, setState2] = useState(); // Error!
}

// react가 여러 훅들을 구분할 수 있는 유일한 정보는 훅이 사용된 순서 뿐이기 때문.

0개의 댓글