2차 공부/TIL

24.10.11 react에서 리스트 매핑중 key를 사용해야하는 이유

공대탈출 2024. 10. 11. 23:53

문제상황

오늘 팀 프로젝트의 mockview와 state들을 만들면서 이러한 오류가 있었다.

학력의 오른쪽 + 버튼을 누르면 아래 3가지 입력창이 계속 생기는 기능을 만들고 있었다.

{eduArray.map((edu, idx) => {
    return (
      <div key={crypto.randomUUID()}>
        <Input
          isLabeled={true}
          labelText="졸업년월"
          value={edu.graduated_at}
          onChange={(e) => handleEduArray(idx, 'graduated_at', e)}
        />
      </div>
    );
})}

이렇게 key에 crypto.randomUUID()를 넣어주어 유니크한 키 값을 가지도록 하였다.

인풋값을 입력할때마다 focus가 풀렸다. 이유가 뭘까??


발생 이유

https://ko.react.dev/learn/rendering-lists#why-does-react-need-keys

리액트 내부 리스트 매핑에서의 key는 결국 리액트가 해당 컴포넌트를 식별하기 위함이다.

컴포넌트 또한 배열로 관리하여 key값으로 비교하게 되는데, 내가 작성한 코드는 리렌더링시마다 crypto.randomUUID()를 재실행하여 새로운 키값을 부여하기 때문에 의도치않은 성능감소와 에러를 발생시켰던 것이다.


해결 시도

  const addForm = (objName: string) => {
    switch (objName) {
      case 'education':
        setEduArray((prev) => [...prev, { ...emptyEduObj, edu_id: crypto.randomUUID() }]);
        break;
      case 'experience':
        setExpArray((prev) => [...prev, { ...emptyExpObj, exp_id: crypto.randomUUID() }]);
        break;
      case 'license':
        setLicArray((prev) => [...prev, { ...emptyLicObj, lic_id: crypto.randomUUID() }]);
        break;
    }
  };

배열에 객체를 추가할 때 랜덤값을 생성하여 각각의 아이디로 주입하였다.

이렇게 되면 생성당시에 값이 추가되어 리렌더링시에도 키값이 변경될 일이 없기 때문에 리액트는 동일한 컴포넌트로 인식하여 focus를 유지하는 것으로 생각했다.


결과

 

리액트가 같은 컴포넌트로 인식하여 리렌더링과 input focus의 버그를 발생시키지 않는 모습이다!

 

https://tecoble.techcourse.co.kr/post/2021-04-25-react-key/

어떤 느낌인지 비교하기 쉬운 사진을 가져와 봤다.