TIL

[TIL] 24_0126 리액트에서의 map사용, key prop 오류

잇츄미 2024. 1. 26. 21:26

 

리액트에서의 map 사용

리액트에선 배열을 받아서 순서있는 엘리먼트 리스트를 출력하는 컴포넌트를 쓸 때 key값을 부여해.

 

-key는 React가 어떤 항목을 변경, 추가, 삭제할 때 식별하는 걸 도와. 엘리먼트에 안정적인 고유성을 부여하기 위해서

배열 내부에 있는 요소에 key속성을 주고 값을 지정해줘야 해. 

예를 들면, 

const ElementKey = () => {

    const array = [ 
     {
      id: 1,
      name : 보라돌이,
     },
     {
      id : 2,
      name : 두비,
     },
     {
      id : 3,
      name : 나나,
     },
     {
      id : 4,
      name : 보,
     }
    ]

return (
         <div>
           {array.map((data) => {
              const { id, name } = data
             return(  
                  <ul key={id}>
         	        <li>{name}</li>
                  </ul>
                )
               }
             )
           }
         </div>  
       ) 
}

 

 

리액트의 map사용해서 순서있는 리스트를 표현할 때,

key속성에 고유한 key값을 주지 않으면 뜨는 오류

 

이 오류는 리액트에서 key값을 주지 않으면 띄워주는 경고이자 오류야.

 

 

key선정 방법

고유한 key값은 해당 요소를 알아볼 수 있는 고유한 문자열을 사용하는 게 가장 좋아.

대부분의 경우 데이터의 ID를 key로 사용해.

cf) 분명 고유한 key값을 줬다고 생각했는데 이런 오류가 났다면 그 고유한 key값을 다른 요소에서도 같이 쓰고 있는거야.

 

 

 

key 사용 방법

<ul>
    {filteredStudents.map((eighteenStudent) => {
          const { name, age, grade } = eighteenStudent;
          return (
          <>
            <div>
              <button onClick={() => onClickInformation(age, grade)}>
                {name}
              </button>
            </div>
          </>  
          );
        })}
</ul>

 

 

예외로 렌더링 할 항목에서 안정적으로 쓸 ID가 없다면 최후의 수단으로 항목의 인덱스를 key로 사용할 수 있어.

하지만,

항목의 순서가 바뀔 수 있는 경우엔 key에 인덱스를 사용하는 건 권장되지 않아. 이걸로 성능이 저하되기도 하고

state와 관련된 문제가 있어. 

 

이 같은 경우 데이터를 기존의 그대로 사용하면 괜찮겠지만 데이터가 중간중간에 추가된다면 index로 쓰는 값이 바뀌어. 그래서 3번째 데이터인 A가 4번째 데이터가 되면서 index번호는 3에서 4가 되는거야. 이런 경우 state값에 영향을 줘.

 

그래서 id 값으로 해당 배열의 length길이에 +1해서 주는 식으로 id의 값을 

const idNum = array.lenght + 1
setState([{...todos, id : idNum}])

or
setState([{...todos, id : idNum}])
idNum ++

이런 식으로 주게 되면 실제로 데이터가 저장됐을 때 실제 데이터는 id가 1,2,3,4 들어있고 화면에 보여주는 건 id가 1, 2 일 때, 다시 새로운 데이터를 생성해서 추가한다면 그 생성된 id의 값은 3이 될거야. 그렇게 데이터가 저장이 되면 원래 데이터 id가 3인 내용은 그 내용으로 수정되거나 덮어쓰여져서 내용이 변질될거구.

 

 

느낀점

- 이번 스탠다드 테스트를 보면서 map 사용할 때 key가 다 index로 되어있었는데 너무 찜찜해서 데이터를 재가공해서 id값을 crypto.randomUUID()를 줬을 때 편안해짐을 느꼈어. 이전에 todoList를 만들었을 때 저장소없이 만들어서 length+1을 줬거든. 그럴 땐 항상 값이 재생성되니까 상관이 없지만 저장소가 생기고 데이터가 전부 새로 생성되는 게 아니라면 length에 +1값을 줘서 id를 주는 건 고유하지 않으닌가 안 쓰는 게 좋은 것 같아. 

 

- crypto.randomUUID()함수 외에 uuid 라이브러리도 있어서 그걸 써보는 것도 좋은 것 같아. 해당 라이브러리를 쓰면 고유한 ID값 줄 때 범위도 줄 수 있어.

 

 

 

*참고 사이트

- https://ko.legacy.reactjs.org/docs/lists-and-keys.html (리액트 공식문서)

- https://www.npmjs.com/package//uuid (uuid 라이브러리 문서. 추가 방법 및 사용 방법 내재)