[React] 8. 배열 렌더링하기

백괴·2021년 8월 26일
0

리액괴

목록 보기
6/14
post-thumbnail

잘못 된 내용에 대한 지적은 환영입니다.

Q. 아래 배열 요소 렌더링 코드의 문제점을 찾으시오 [null점]

export default function UserList() {
  const users = [
    {
      id: 1,
      username: "uncyclocity",
      email: "seongbeom_lee@kakao.com",
    },
    {
      id: 2,
      username: "yoong_kim",
      email: "dl2qja@gmail.com",
    },
    {
      id: 3,
      username: "sblee",
      email: "xuct227@gmail.com",
    },
  ];

  return (
    <>
      <div>
        <b>{users[0].username}</b> <span>({users[0].email})</span>
      </div>
      <div>
        <b>{users[1].username}</b> <span>({users[1].email})</span>
      </div>
      <div>
        <b>{users[2].username}</b> <span>({users[2].email})</span>
      </div>
    </>
  );
}

A. 재사용 가능한 동일한 구조의 코드가 반복되고 있다.

보다 깔끔한 코드로 변경하기

  1. 반복되는 코드를 별도의 컴포넌트로 분리한다.
   // 별도의 컴포넌트로 분리 된 코드
   function User({ user }) {
     return (
       <div>
         <b>{user.username}</b> <span>{user.email}</span>
       </div>
     );
   }

   export default function UserList() {
     const users = [
       {
         id: 1,
         username: "uncyclocity",
         email: "seongbeom_lee@kakao.com",
       },
       {
         id: 2,
         username: "yoong_kim",
         email: "dl2qja@gmail.com",
       },
       {
         id: 3,
         username: "sblee",
         email: "xuct227@gmail.com",
       },
     ];

     return (
       <div>
         <User user={user[0]} />
         <User user={user[1]} />
         <User user={user[2]} />
       </div>
     );
   }
  • User라는 이름의 별도 컴포넌트로 분리하였으므로 한층 깔끔해졌으나, 아직 렌더링 부분에서 같은 코드가 반복되고 있다.
  1. 배열 내장함수 map 을 이용하여, 각 배열 요소에 대해 루프를 돌아 반복되는 컴포넌트들을 렌더링한다.
   function User({ user }) {
     return (
       <div>
         <b>{user.username}</b> <span>{user.email}</span>
       </div>
     );
   }

   export default function UserList() {
     const users = [
       {
         id: 1,
         username: "uncyclocity",
         email: "seongbeom_lee@kakao.com",
       },
       {
         id: 2,
         username: "yoong_kim",
         email: "dl2qja@gmail.com",
       },
       {
         id: 3,
         username: "sblee",
         email: "xuct227@gmail.com",
       },
     ];

     return (
       <div>
         {users.map((user) => (
           <User user={user} />
         ))}
       </div>
     );
   }
  • 사실 여기서도 문제는 존재하는데, 바로 map 함수에서 각 원소의 고유값을 지정하지 않았다는 것이다.
    👉 이는 배열 업데이트의 효율성을 해치게 되므로 아래처럼 key 속성으로 지정해준다.
   users.map(user =>(
   // key는 각 원소의 고유값으로 지정해야 한다.
   <User user={user} key={user.id}>
   ))
  • 각 원소의 고유값에 해당하는 값이 없을 경우, map 함수의 두 번째 파라미터 index를 사용해도 되지만, 어디까지나 배열의 index를 사용하는 것이므로 권장하지 않는다.
   users.map((user, index) =>(
      <User user={user} key={index}>
   ))

map 함수에서 key 유무의 차이

(해당 내용은 벨로퍼트님 글에서 영상을 통해 보다 쉽게 이해할 수 있다.)

  • key

    • 삽입
      중간에 값을 집어넣으면 뒤의 값들이 차례차례 기존의 앞의 값으로 바뀐다.
      ➡ 마지막에 기존의 맨 끝 값이 새로 삽입된다.

    • 삭제
      중간에 값을 삭제하면, 삭제한 시점부터 차례차례 기존의 뒤의 값으로 바뀐다.
      ➡ 마지막 값이 삭제된다.

    • 이유 : 임시방편으로 배열 각 요소의 index 값을 key로 사용하기 때문이다.

  • key

    • 삽입
      중간에 값을 집어넣으면 기존 배열 요소들의 변화 없이 원하는 곳에 삽입된다.

    • 삭제
      중간에 값을 삭제하면 기존 배열 요소들의 변화 없이 해당 값만 삭제된다.

References

"11. 배열 렌더링하기" .velopert

2개의 댓글

comment-user-thumbnail
2021년 9월 17일

삽입, 삭제가 이루어지는 동적인 배열에서 key 속성을 index로 넣었다가
문제 찾느라 한참 삽질했던 적이 있어요

1개의 답글