ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JSX] Key 속성이란 무엇일까?
    개발/React (페이지 제작과정) 2023. 8. 15. 07:26
    728x90
    반응형

    전글에서 map에 대해서 설명을 했었다. 만약 보지 않았다면 전 글을 보고 이 글을 읽는 것을 추천한다.

    https://hueeng.tistory.com/40

     

    Key 속성 정의?

    JavaScript에서 객체를 사용할 때, 객체의 각 속성에 대한 식별자 역할을 하는 것을 "키(Key)"라고 한다. 객체는 중괄호 {} 안에 이름-값 쌍 형태로 구성되며, 각 이름(속성명)을 통해 해당 속성의 값을 가져오거나 설정할 수 있다. 이때 이름을 가리키는 것이 바로 "키"라고 한다. 여기서 아래 예제코드를 보자

     

    예제를 곁들인 설명

    const residents = [
      { name: 'Alice', age: 25 },
      { name: 'Bob', age: 30 },
      { name: 'Charlie', age: 28 },
    ];

    위의 객체에서 name, age는  각각 키이다. 각 키는 객체 내의 해당 속성에 접근할 때 사용된다. 예를 들어 person.name'Alice'를 반환하며, person.age25를 반환하는 것이다.

     

    Key의 중요성

    컴포넌트 리스트를 렌더링하거나 업데이트할 때 효율적인 동작을 보장하기 위해 각 컴포넌트에 고유한 키를 지정하는 것이 중요하다. 이렇게 함으로써 리액트는 컴포넌트의 추가, 제거, 재배열 등을 더 효율적으로 처리할 수 있다.

     

    Warning: Each child in a list should have a unique "key" prop

    만약 키를 넣지않는다면 위와 같은 에러코드가 나타날 것이다.

    해당하는 속성값을 찾을 수 없기 때문이다. 

     

    Key에는 어떤 값이 들어가야 할까?

    당연히 유니크한 값이 들어가야 한다. 전 페이지에서는 index를 넣었는데 index는 넣는 걸 추천하지 않는다고 했다. 왜 index는 비추천일까? 

     

    업데이트 효율성 문제: 배열의 인덱스는 해당 아이템의 위치를 나타내는 값이지만, 아이템의 순서가 변경되거나 아이템이 추가되거나 삭제될 때 인덱스 값이 변경될 수 있다. 이런 경우 리액트는 아이템의 위치 변화를 감지하지 못하고, 인덱스 값만으로 렌더링을 수행하기 때문에 예상치 못한 결과가 발생할 수 있다.

     

    성능 문제: 인덱스를 key 값으로 사용하면 리스트 내에서 아이템이 이동하거나 추가/삭제되는 경우 리액트가 각 아이템을 완전히 재생성해야 할 수 있다. 이는 성능 저하를 만든다. 만약 고유한 식별자가 없어서 인덱스를 key로 사용해야 하는 상황이라면, 해당 리스트가 정적이거나 변화가 적은 경우에만 적용해야 하는데 이럴 경우 굳이 쓰지 말고 id를 지정하자.

     

    ★고유성 보장 문제: 배열의 인덱스는 고유한 식별자가 아닐 수 있다. 예를 들어, 두 개의 배열이 합쳐진 경우 같은 인덱스 값이 중복될 수 있다. 이런 경우 key 값의 고유성이 보장되지 않을 수 있는데 이러면 원하는 값이 나오지 않는다. 

     

    객체를 생성할 때 id 를 생성하자

     

    const residents = [
      { id : 1 , name: 'Alice', age: 25 },
      { id : 2 , name: 'Bob', age: 30 },
      { id : 3 , name: 'Charlie', age: 28 },
    ];

    위 코드는 객체를 생성할때 속성에 id를 추가해 주었다 만약 id를 key값으로 사용한다면 위에서 나타나는 모든 문제를 해결 가능하다. 그렇다 보니 기본적으로 데이터를 다룰 때는 id를 key값으로 사용하게 된다.

     

     

    내가 진행하고 있는 프로젝트 예제

    if (data && Array.isArray(data) && data.length > 0) {
          return (
            <div>
                <StudentDataTable>
                  <thead>
                    <tr>
                      <th>번호</th>
                      <th>이름</th>
                      <th>성별</th>
                      <th>학번</th>
                      <th>차수</th>
                      <th>현재상태</th>
                      <th>생년월일</th>
                      <th>기숙사</th>
                      <th>전공</th>
                      <th>학년</th>
                      <th>기간</th>
                      <th>호실</th>
                      <th>배정방</th>
                      <th>입사일자</th>
                      <th>퇴사일시</th>
                      <th>차수시작일</th>
                      <th>차수종료일</th>
                      <th>HP</th>
                      <th>사회코드</th>
                      <th>사회명</th>
                      <th>ZIP</th>
                      <th>주소</th>
                      <th>삭제</th>
                    </tr>
                  </thead>
                  <tbody>
                    {data.map((resident, index) => (
                      <tr key={resident.id}>
                        <td>{index + 1}</td>
                        <td>{resident.name}</td>
                        <td>{resident.gender}</td>
                        <td>{resident.studentId}</td>
                        <td>{resident.period}</td>
                        <td>{resident.currentStatus}</td>
                        <td>{resident.dateOfBirth}</td>
                        <td>{resident.dormitory}</td>
                        <td>{resident.major}</td>
                        <td>{resident.grade}</td>
                        <td>{resident.semester}</td>
                        <td>{resident.roomNumber}</td>
                        <td>{resident.assignedRoom}</td>
                        <td>{resident.admissionDate}</td>
                        <td>{resident.leavingDate}</td>
                        <td>{resident.semesterStartDate}</td>
                        <td>{resident.semesterEndDate}</td>
                        <td>{resident.phoneNumber}</td>
                        <td>{resident.socialCode}</td>
                        <td>{resident.socialName}</td>
                        <td>{resident.zipCode}</td>
                        <td >{resident.address}</td>
                        <td>
                          <button
                            onClick={() => StudentDelete(resident.id, props.Token)}
                          >
                            삭제
                          </button>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </StudentDataTable>
            </div>
          );

    자 나처럼 이렇게 기숙사 학생관련 데이터를 출력하려고 한다면 첫 번째로 앞에서 배웠던 map을 활용해야 한다. 그리고 그 map의 resident.id를 나는 key 값으로 사용한다. 물론 객체를 생성하고 다루는 코드는 백엔드 자료에 들어가 있다. 이렇게 하면 표로 모든 데이터를 출력하게 된다.

     

    map과 key를 이용한다면 데이터를 다루는 웬만한 코드들은 작성할 수 있게된다. key를 이용해서 해당항목을 삭제할 수 도 있게 되며 추가할 수 도 있게 된다.

     

    당연히 가장 간단한 건 TODO사이트를 제작해 봐라

     

    728x90
    반응형
Designed by Tistory.