문제상황
오늘 팀 프로젝트의 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가 풀렸다. 이유가 뭘까??
발생 이유
리액트 내부 리스트 매핑에서의 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의 버그를 발생시키지 않는 모습이다!
어떤 느낌인지 비교하기 쉬운 사진을 가져와 봤다.
'2차 공부 > TIL' 카테고리의 다른 글
24.10.15 tailwind에서 제공하지 않는 style속성 사용하기 (0) | 2024.10.15 |
---|---|
24.10.14 supabase.insert, promise.all과 transaction (1) | 2024.10.15 |
24.10.08 개인프로젝트 마무리 (2) | 2024.10.08 |
24.10.07 nextjs 에러핸들링 (0) | 2024.10.08 |
24.10.02 개인프로젝트 트러블슈팅 (0) | 2024.10.02 |