Develope/React

[React]반복문으로 컴포넌트 렌더링시 고유값을 부여하는 이유

oper0116 2020. 6. 23. 23:24
반응형

Key 속성에 따른 재사용성

Each child in an array should have a unique "key" prop. Check the render method of Component.

List 형태 등의 데이터를 통해 컴포넌트를 구성하다 보면 위의 경고 메시지를 보신 적이 있을 것입니다.
해당 경고 메시지는 각각의 컴포넌트에 고유 'key'값을 가져야 하기 때문에 컴포넌트를 확인해달라는 내용으로써, 컴포넌트에 key 속성 값을 고윳값으로 가지도록 수정한다면 해당 경고 메시지를 해결할 수 있습니다.

key 속성에 고유의 값을 부여하면 이 데이터는 어떻게 쓰일까요? 부여받은 key를 통해 기존 트리와 이후 트리의 자식들이 일치하는지 확인하는 값으로 사용하고 있다고 합니다.

<ul>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

<ul>
  <li key="2014">Connecticut</li>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

2014 key를 가진 엘리먼트는 새롭게 생성되어 추가되었으며, 20152016의 key를 가진 엘리먼트를 기존에 생성되었던 엘리먼트를 재사용하여 사용되고 있습니다.

React 공식문서에서는 해당 내용을 다음과 같이 설명하고 있습니다.
이 내용을 좀 더 명시적으로 확인하기 위하여 key 속성값이 변경되는 경우와 key 속성값을 변경되지 않는 경우에 대하여 컴포넌트가 mount, unmount 될 경우 로그가 출력되도록 코드를 작성하였습니다.

버튼 선택 시 key 변경되는 경우

const Item = (props) => {
  useEffect(() => {
    console.debug("component mount");
    return () => {
      console.debug("component unmount");
    }
  }, []);
  return <div>전달받은 {props.id}</div>;
};

const App = () => {
  const [ id, setId ] = useState(0);
  return (
    <div className="App">
      <Item key={id} id={id}/>
      <button onClick={() => setId(Math.random())}>id값 변경</button>
    </div>
  );
}

버튼 선택 시 key값이 변경되지 않는 경우

const Item = (props) => {
  useEffect(() => {
    console.debug("component mount");
    return () => {
      console.debug("component unmount");
    }
  }, []);
  return <div>전달받은 {props.id}</div>;
};

const App = () => {
  const [ id, setId ] = useState(0);
  return (
    <div className="App">
      <Item key={0} id={id}/>
      <button onClick={() => setId(Math.random())}>id값 변경</button>
    </div>
  );
}

key값이 변경될 경우에는 mount, unmount시 발생하는 로그가 출력되고 있지만, 변경되지 않을 경우에는 해당 로그가 출력되지 않습니다. 따라서 key값에 따라 컴포넌트가 재사용될 수도 또는 다시 렌더링 될 수도 있다는 걸 확인할 수 있습니다.

결론

key값에 고유값이 아닌 Math.random() 값과 같이 변화하는 값을 사용하게 된다면 의도치 않은 렌더링이 발생시킬 수 있으며, 이러한 의도치 않은 렌더링은 퍼포먼스 측면에서 영향을 끼칠 것입니다. 따라서 의도치 않은 렌더링을 막기 위해서 key 속성값에 고윳값을 입력하도록 해야 합니다.

참고자료

(React Docs: reconciliation)[https://reactjs.org/docs/reconciliation.html#keys]

반응형