[React] Props 변경 시 상태 초기화하기 (not UseEffect, but Key)

    728x90
    반응형

     

     

    [React] Props 변경 시 상태 초기화하기

    리액트를 사용하다보면 상세페이지처럼 path정보를 받아와서 랜더링하는 경우,

    리셋 후 새로운 정보를 가져오는게 아니고 이전 데이터가 그대로 랜더링 되는 경우를 경험해봤을 수 있습니다.

    이러한 경우 보통 useEffect를 가지고 path 정보가 달라지면 (ex: useId) 새 데이터를 호출하거나 하는 방법을 사용했었는데, 여기서 key를 이용해서 간단히 해결하는 것을 보고 블로그에 남기려고 합니다.

     

    React 컴포넌트에서 userId prop을 받고, 댓글 입력을 위한 comment 상태 변수가 있는 경우를 생각해봅시다.

    사용자가 다른 프로필로 이동할 때 댓글 상태가 초기화되지 않아 잘못된 프로필에 댓글을 남길 수 있습니다.

     

     

     

    잘못된 접근 방법

    처음에는 useEffect를 사용해 userId가 변경될 때 comment 상태를 초기화하는 방법을 생각할 수 있습니다:

    export default function ProfilePage({ userId }) {
      const [comment, setComment] = useState('');
    
      useEffect(() => {
        setComment('');
      }, [userId]);
    
      // ...
    }

     

    하지만, 이 방법은 비효율적입니다.

    컴포넌트와 자식 컴포넌트가 먼저 이전 값을 사용해 렌더링된 후 다시 렌더링되어야 하기 때문입니다.

    또한, 중첩된 상태를 초기화해야 할 때 복잡해집니다.

     

     

     

     

    올바른 접근 방법: Key 속성 사용

    대신, React에 각 프로필이 개념적으로 다른 프로필임을 명시하기 위해 key 속성을 사용할 수 있습니다.

    먼저, 컴포넌트를 둘로 나누고, 외부 컴포넌트에서 내부 컴포넌트로 key 속성을 전달합니다:

    export default function ProfilePage({ userId }) {
      return (
        <Profile
          userId={userId}
          key={userId}
        />
      );
    }
    
    function Profile({ userId }) {
      const [comment, setComment] = useState('');
      // ...
    }

     

    이렇게 하면 userId가 변경될 때 React는 두 개의 Profile 컴포넌트를 서로 다른 컴포넌트로 간주하여 상태를 공유하지 않게 됩니다.

    key가 변경될 때마다 React는 Profile 컴포넌트와 모든 자식 컴포넌트를 다시 생성하고 상태를 초기화합니다.

     

     

     

     

    요약

    • props 변경 시 상태를 초기화하기 위해 useEffect를 사용하는 것은 비효율적일 수 있습니다.
    • 대신, key 속성을 사용하여 React가 컴포넌트를 서로 다른 컴포넌트로 간주하도록 할 수 있습니다.
    • 이를 통해 상태가 자동으로 초기화되고, 불필요한 재렌더링을 방지할 수 있습니다.

    이제 사용자가 프로필을 변경할 때 댓글 입력 상태가 자동으로 초기화됩니다.

    ProfilePage 컴포넌트는 다른 파일에서 userId를 일반 prop으로 전달받고, key로 사용하는 것은 내부 구현 세부 사항이 됩니다.

     

     

     

     

     

     

     

    참조:

    https://react.dev/learn/you-might-not-need-an-effect

     

    You Might Not Need an Effect – React

    The library for web and native user interfaces

    react.dev

     

    728x90
    반응형

    'react.js' 카테고리의 다른 글

    [React] useEffectEvent hook  (0) 2024.06.10
    [React] useSyncExternalStore (외부 데이터 구독 새로운 방법)  (0) 2024.06.09
    [React] react에서의 Side Effect  (0) 2024.06.09
    [React] flushSync  (0) 2024.06.08
    [React] forwardRef  (0) 2024.06.08

    댓글