Each child in a list should have a unique "key" prop.

김종원·2022년 8월 24일
0

[TIL (Today I Learned)]

목록 보기
29/45
        <MenuUl>
          {name.map(function (a, i) {
            return (
              <MenuLi
                onClick={() => {
                  setTypeNum(i + 1);
                  setCurrNum(i);
                }}
              >
                <MenuDiv aria-current={currNum === i ? 'currNum' : null}>
                  {name[i]}
                </MenuDiv>
                <Rectangle aria-current={currNum === i ? 'currNum' : null} />
              </MenuLi>
            );
          })}
        </MenuUl>

Map을 이용하여 로직을 작성하던 중 콘솔에서 " Warning: Each child in a list should have a unique "key" prop "이라는 주의 문구를 확인하였습니다.

발생한 이유를 찾아보니 React는 key prop을 사용하여 컴포넌트와 DOM 요소 간의 관계를 생성하는데
리액트 라이브러리는 이 관계를 이용해 컴포넌트 리렌더링 여부를 결정한다고 한다.
그래서 불필요한 리렌더링을 방지하기 위해서는 각 자식 컴포넌트마다 독립적인 key값을 넣어줘야 한다고 합니다.

해결방법은 key prop을 자식 컴포넌트마다 넣어주는 것입니다.

하지만

        <MenuUl>
          {name.map(function (a, i) {
            return (
              <MenuLi
                key={i}
                onClick={() => {
                  setTypeNum(i + 1);
                  setCurrNum(i);
                }}
              >
                <MenuDiv key={i} aria-current={currNum === i ? 'currNum' : null}>
                  {name[i]}
                </MenuDiv>
                <Rectangle aria-current={currNum === i ? 'currNum' : null} />
              </MenuLi>
            );
          })}
        </MenuUl>

key에 "i"를 넣어주니 동일한 주의문구가 콘솔창에 발생하였습니다.

자바스크립트의 배열은 정적이지 않기 때문에 배열의 길이나 원소 등이 변할 수 있는데 배열의 index를 key prop으로 사용해서 발생한 문제였습니다.

배열의 원소의 순서가 바뀌면 index도 바뀌고 컴포넌트마다 고유해야 하는 key값도 같이 바뀌기 때문이다.
이렇게 되면 리액트는 리렌더링 해야하는 컴포넌트를 헷갈려 잘못된 컴포넌트를 리렌더링할 수 있다.

그래서

        <MenuUl>
          {name.map(function (a, i) {
            return (
              <MenuLi
                key={name[i]}
                onClick={() => {
                  setTypeNum(i + 1);
                  setCurrNum(i);
                }}
              >
                <MenuDiv key={name[i]} aria-current={currNum === i ? 'currNum' : null}>
                  {name[i]}
                </MenuDiv>
                <Rectangle aria-current={currNum === i ? 'currNum' : null} />
              </MenuLi>
            );
          })}
        </MenuUl>

name[i] 자체를 Key값으로 설정해주었더니

주의문구가 사라지는 것을 확인할 수 있었습니다.!

profile
발전하기위한 기록

0개의 댓글