Skip to content

React의 고유한 key

Znero edited this page Dec 1, 2024 · 1 revision

문제사항

새로운 쉘을 만들때 ShellId 값을 new Date().getTime()으로 부여했다.

    const newShell: ShellType = {
      shellId: new Date().getTime(),
      queryStatus: null,
      runTime: null,
      query: null,
      queryType: null,
      failMessage: null,
      affectedRows: null,
      table: null,
    }

그리고 키값으로 shell.shellId(생성시간)을 줬다.

{shells.map((shell) => (
    <Shell
        key={shell.shellId}
        shell={shell}
        removeShell={removeShell}
        focusedShell={focusedShell}
        setFocusedShell={setFocusedShell}
    />
))}

경고 등장!!

스크린샷 2024-11-12 오전 1 28 54


React key란?

Key는 각 컴포넌트가 어떤 배열 항목에 해당하는지 React에 알려주어 나중에 일치시킬 수 있도록 함. 
  • 배열 항목이 이동, 삽입, 삭제 될 수 있는 경우에 key가 몹시 중요
  • key를 잘 선택하면 React가 정확히 무슨 일이 알아내고 DOM 트리에업데이트 하는데 도움이 됨

왜 key는 즉석해서 생성하면 안 될까?

  • 렌더링 간에 key가 일치하지 않아 모든 컴포넌트와 DOM이 매번 다시 생성될 수 있음
  • 속도가 느려질 뿐만 아니라 리스트 항목 내부의 모든 입력이 손실될 수 있음
  • 데이터 기반의 안정적인 ID를 사용해야함

데이터 소스마다 다른 key 소스를 제공합니다

  • 데이터베이스의 데이터: 데이터베이스에서 데이터를 가져오는 경우 본질적으로 고유한 데이터베이스 key/ID를 사용할 수 있습니다.
  • 로컬에서 생성된 데이터: 데이터가 로컬에서 생성되고 유지되는 경우(예: 메모 작성 앱의 노트), 항목을 만들 때 증분 일련번호나 crypto.randomUUID 또는 uuid같은 패키지를 사용하세요.



해결 방법

쉘 아이디

  • 서버에서 쉘 아이디를 생성하고, 이를 받기로 결정
  • 그 전까지 쉘 아이디는 null

shell.id가 없을떄만 uuid 사용하게 변경

{shells.length > 0 && (
    <div className="flex flex-1 flex-col gap-3 p-4">
        {shells?.map((shell) => (
            <Shell
                key={shell.id || uuidv4()} //shell.id가 없을떄만 uuid 사용
                shell={shell}
                removeShell={removeShell}
                updateShell={updateShell}
                focusedShell={focusedShell}
                setFocusedShell={setFocusedShell}
            />
        ))}
    </div>
)}

기타

  • id 속성이 있는경우 해당 id를 키로 사용
  • 만약 id 속성이 없다면 해당 객체를 string으로 만들고, uuid와 조합해 키로 사용
import { v4 as uuidv4 } from 'uuid'

export default function generateKey(obj: Record<string, unknown>) {
  if (!obj.id) return JSON.stringify(obj.id)
  return `${JSON.stringify(obj)}-${uuidv4}`
}

참고자료

Clone this wiki locally