본문 바로가기
FrontEnd/React

리액트 | 커스텀 훅에서 변경한 전역 상태가 컴포넌트에 반영되지 않을 때 해결 방법 🙌🏻

by Noo-Dabee 2023. 3. 9.
반응형

커스텀 훅에서 변경된 리코일 상태가 컴포넌트에 반영되지 않는 이유는 여러가지가 있을 수 있지만, 이 포스트에서는 리액트 라이프사이클과 관련된 내용을 다루고 있습니다.

커스텀 훅에서 전역 상태를 업데이트했는데, 컴포넌트 리렌더링은 일어나지 않는다?! 😣

리코일로 관리하는 상태를 업데이트해주는 커스텀 훅을 사용하는데, 상태가 업데이트 되어도 컴포넌트 리렌더링이 일어나지 않는다면 커스텀 훅에 useEffect() 훅을 통해 컴포넌트의 라이프사이클을 잘 제어하고 있는지 먼저 확인해보는게 좋습니다.

커스텀 훅은 일반적으로 리액트 컴포넌트 내부에서 사용됩니다. 컴포넌트는 상태(state) 또는 속성(props)이 변경될 때마다 다시 렌더링됩니다. 그러나 커스텀 훅은 컴포넌트의 라이프사이클과는 별개로 동작하기 때문에, 훅에서 상태를 변경하더라도 컴포넌트의 다시 렌더링이 자동으로 발생하지 않습니다. 따라서, 커스텀 훅에서 리코일 상태를 변경한 후에는 해당 상태가 컴포넌트에 바로 반영되지 않습니다.

대신, 리코일 상태를 변경한 후에 컴포넌트가 다시 렌더링되도록 강제로 트리거해주어야 합니다. 이를 위해서는 일반적으로 리액트의 useState 훅에서 사용하는 setState 함수와 유사한 set 함수를 사용하면 됩니다.

예시 🧑🏻‍💻

예를 들어, 다음과 같이 useCustomHook이라는 커스텀 훅이 있고, 이 훅에서 리코일 상태를 변경하는 updateState 함수가 있다고 가정해보겠습니다.

다음은 잘못 작성된 예시입니다. 이 커스텀 훅은 초기값을 받아서 카운트 상태와 해당 상태를 증가시키는 increment 함수를 반환합니다.

import { useState } from 'react';

export function useCounter(initialCount) {
  const [count, setCount] = useState(initialCount);

  function increment() {
    setCount(count + 1);
  }

  return { count, increment };
}

그리고 다음과 같이 useCounter를 사용하는 컴포넌트가 있다고 가정해보겠습니다. 이 컴포넌트는 useCounter를 사용하여 초기값이 0인 카운터를 만들고, 해당 카운터를 렌더링하는 역할을 합니다.

import { useCounter } from './useCounter';

function Counter() {
  const { count, increment } = useCounter(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

여기서 문제는, increment 함수에서 setCount를 호출하여 상태를 업데이트하더라도 컴포넌트가 다시 렌더링되지 않는다는 것입니다. 따라서 버튼을 클릭해도 카운터 값이 갱신되지 않습니다.

이를 해결하기 위해서는, increment 함수에서 setCount를 호출한 후에 useEffect 훅을 사용하여 컴포넌트가 다시 렌더링되도록 해주어야 합니다. 예를 들어, 다음과 같이 수정할 수 있습니다.

import { useState, useEffect } from 'react';

export function useCounter(initialCount) {
  const [count, setCount] = useState(initialCount);

  useEffect(() => {
    console.log('Count updated:', count);
  }, [count]);

  function increment() {
    setCount(count + 1);
  }

  return { count, increment };
}

이제 useEffect 훅을 사용하여 카운터 값이 변경될 때마다 콘솔에 로그를 출력하도록 만들었습니다. 이제 Counter 컴포넌트에서 increment 함수를 호출하면, 로그가 출력되고 카운터 값이 갱신됩니다.

import { useCounter } from './useCounter';

function Counter() {
  const { count, increment } = useCounter(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

결과적으로, useEffect 훅을 사용하여 컴포넌트의 라이프사이클을 제어하여 커스텀 훅에서 변경된 상태가 컴포넌트에 반영되도록 만들 수 있습니다.

 

반응형

댓글