본문 바로가기
Frontend/React

Custom Hooks 개념 및 사용 방법

by Forsaken Developer 2023. 2. 2.
728x90
728x90

Custom Hooks 개념 및 사용 방법

커스텀 훅은 결국은 useState와 같은 내장 hook처럼 정규 함수이다.

하지만 안에 상태를 설정할 수 있는 로직을 포함한 함수이다.

커스텀 훅을 통해, 다른 컴포넌트에서 사용할 수 있는 로직을 커스텀 훅으로 아웃소싱할 수 있으며, 이를 통해 다양한 컴포넌트에서 호출이 가능하다.

아래 코드에서 사용된 BackwardCounter와 ForwardCounter는 App에서 컴포넌트로 사용되고 있다.

ForwardCounter와 BackwardCounter는 모두 useState와 useEffect를 통해 상태를 관리하고, 시간 간격을 만들어서 매 초 마다 새로운 카운터 상태를 설정한다.

똑같은 일을 하지만 한 가지 다른점은 역방향으로 카운팅을 한다.

이 것 외에는 둘 모두 동일한 로직이며 이 두 컴포넌트는 매우 유사하다고도 할 수 있다.

덧셈과 뺄셈이라는 작은 차이만 제외한다면 이 둘은 정확히 동일한 코드이기때문에 이럴때 보통은 중복되는 부분을 떼어내고 공통의 코드를 갖는 함수를 만든다.

이 것이 커스텀 훅을 사용하는 이유이다.

훅의 규칙에 의하면 다른 함수에서 이러한 리액트 훅을 사용하는 것은 불가능하지만 리액트 컴포넌트 함수나 커스텀 훅에서는 사용할 수 있다.

const BackwardCounter = () => {
  const [counter, setCounter] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setCounter((prevCounter) => prevCounter - 1);
    }, 1000);

    return () => clearInterval(interval);
  }, []);

  return <Card>{counter}</Card>;
};

export default BackwardCounter;
const ForwardCounter = () => {
  const [counter, setCounter] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setCounter((prevCounter) => prevCounter + 1);
    }, 1000);

    return () => clearInterval(interval);
  }, []);

  return <Card>{counter}</Card>;
};

export default ForwardCounter;

커스텀 훅은 이름이 무조건 use로 시작해야 한다.

일반적인 함수지만 이 이름 앞에 붙인 use는 리액트에게 이 함수가 커스텀 훅임을 알려주며 이는 리액트가 해당 함수를 훅의 규칙에 따라 사용하겠다고 보장해주는 것이다.

그렇지 않으면 커스텀 훅을 잘못된 곳에서 사용하게 된다면 내장 훅 역시 잘못된 곳에서 쓸 수 있다.

이 것이 use로 이름이 시작하게끔 하는 이유로 이렇게 해야 리액트가 확인을 하고 훅의 규칙을 위반한 것이 발견되었을 때 경고를 보낼 수 있다.

컴포넌트 안에서 커스텀 훅을 호출하면 이 컴포넌트의 어떤 상태나 효과는 커스텀 훅을 사용하는 컴포넌트에 묶이게 되며 다수의 컴포넌트에서 커스텀 훅을 사용하게 되면 모든 컴포넌트가 각자의 상태를 받는다.

커스텀 훅을 사용한다고 해서 컴포넌트 전반에 걸쳐서 상태나 효과를 공유하는 것은 아니고 로직만 공유한다.

const useCounter = () => {
  const [counter, setCounter] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
    }, 1000);

    return () => clearInterval(interval);
  }, []);
  return counter;
};

export default useCounter;

커스텀 훅이 관리하는 상태에 접근하기 위해서는 내장 훅을 사용할 때와 똑같이 하면 된다.

커스텀 훅은 함수이므로, 어떤 것이든 반환할 수 있다.

여기 커스텀 훅에서는 counter의 상태를 사용 가능하게 이를 반환만 하면 된다.

const ForwardCounter = () => {
  const counter = useCounter();
  return <Card>{counter}</Card>;
};

export default ForwardCounter;

BackwardCounter와 ForwardCounter에서 다르게 동작하기 위해서는 커스텀 훅에서 별도의 처리가 필요하다.

내장 훅인 useState 또한 초기 상태를 설정하는 매개변수를 받을 수 있고 useEffect 훅은 2개의 매개변수를 받을 수 있는 것처럼 커스텀 훅도 함수이기 때문에 매개변수를 받을 수 있다.

덧셈을 할 지, 뺄셈을 할 지 제어를 하는 boolean flag를 사용할 수 있다.

forwards라고 명명한 매개변수를 통해서 true면 덧셈을 false면 뺄셈을 하게 한다.

const useCounter = (forwards = true) => {
  const [counter, setCounter] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      if (forwards) {
        setCounter((prevCounter) => prevCounter + 1);
      } else {
        setCounter((prevCounter) => prevCounter - 1);
      }
    }, 1000);

    return () => clearInterval(interval);
  }, [forwards]);
  return counter;
};

export default useCounter;
728x90
반응형

댓글