이롭게 현명하게

[React] 리액트 배열 렌더링하기 본문

웹 개발/React

[React] 리액트 배열 렌더링하기

dev_y.h 2023. 12. 27. 18:09
728x90
반응형

※ 본 포스팅은 윈도우11 환경에서 패스트 캠퍼스 강의를 수강하며 정리한 내용입니다.

 


 

목차

 

배열 렌더링

key의 존재 유무에 따른 업데이트 방식

 

 


 


[배열 렌더링]

다음과 같은 배열이 있다.

const users = [
  {
    id: 1,
    username: 'uni',
    email: 'uni@gmail.com'
  },
  {
    id: 2,
    username: 'dog',
    email: 'dog@gmail.com'
  },
  {
    id: 3,
    username: 'cat',
    email: 'cat@gmail.com'
  }
];

 

<배열을 렌더링 하는 방법>

  1. 그대로 사용하기
  2. 컴포넌트 생성
  3. 동적 배열 사용시 map함수 사용

 

 

이 배열을 컴포넌트로 렌더링 한다면 어떻게 해야 할까?

<배열을 그대로 사용하여 렌더링>

import React from "react";

function UserList(){
    const users =[
        {
            id : 1,
            username : 'uni',
            email : 'uni@gmail.com'
        },
        {
            id : 2,
            username : 'dog',
            email : 'dog@gmail.com'
        },
        {
            id : 3,
            username : 'cat',
            email : 'cat@gmail.com'
        }
    ];

    return(
        <div>
            <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>
        </div>
    );

}

export default UserList;

그대로 사용한다면 같은 코드를 반복적으로 사용하기 때문에 비효율적이다.

 

만약 배열 길이가 고정적이라면 컴포넌트를 하나 더 생성하여 사용할 수 있다.

<컴포넌트를 하나 더 생성하여 사용>

import React from "react";

function User({user}){//props로 user를 받아온다.
    return(
        <div>
            <b>{user.username}</b> <span>{user.email}</span>
        </div>
    );

}

function UserList(){
    const users =[
        {
            id : 1,
            username : 'uni',
            email : 'uni@gmail.com'
        },
        {
            id : 2,
            username : 'dog',
            email : 'dog@gmail.com'
        },
        {
            id : 3,
            username : 'cat',
            email : 'cat@gmail.com'
        }
    ];

    return(
        <div>
            <User user={users[0]}/>
            <User user={users[1]}/>
            <User user={users[2]}/>
        </div>
        
    );

}

export default UserList;

 


배열이 고정적이지 않고 동적인 배열을 렌더링 하려면 자바스크립트 배열의 내장함수 map()을 사용해야 한다.

 

map() 함수는 배열 안에 있는 각 원소를 변환하여 새로운 배열을 만들어준다.

리액트에서 동적인 배열을 렌더링해야 할 때는 map 함수를 사용하여 일반 데이터 배열을 리액트 Element로 이루어진 배열로 변환해 준다.

<map함수 사용하기>

이 코드에서는 id가 고유 값이다.

import React from "react";

function User({user}){//props로 user를 받아온다.
    return(
        <div>
            <b>{user.username}</b> <span>{user.email}</span>
        </div>
    );

}

function UserList(){
    const users =[
        {
            id : 1,
            username : 'uni',
            email : 'uni@gmail.com'
        },
        {
            id : 2,
            username : 'dog',
            email : 'dog@gmail.com'
        },
        {
            id : 3,
            username : 'cat',
            email : 'cat@gmail.com'
        }
    ];

    return(
        <div>
            {
                users.map(
                    user =>(<User user={user}/>)
                )
            }
        </div>
        
    );

}

export default UserList;

 

 

UserList.js:31 Warning: Each child in a list should have a unique "key" prop.

경고 메시지가 뜨는 이유 : 각 고유 원소에 key가 있어야만 배열이 업데이트될 때 효율적으로 렌더링 될 수 있다.

리액트에서 배열을 렌더링할 때는 key라는 props를 설정해야 한다.

key 값은 각 원소들마다 가지고 있는 고유 값으로 설정해야 한다.

 return(
        <div>
            {
                users.map(
                    user =>(<User user={user} key={user.id}/>)
                )
            }
        </div>
        
    );

 

만약 배열 안의 원소가 가지고 있는 고유한 값이 없다면 map() 함수를 사용할 때 설정하는 콜백함수의 두 번째 파라미터 index를 key로 사용하면 안 된다.

만약에 배열을 렌더링할 때 key 설정을 하지 않게 된다면 기본적으로 배열의 index 값을 key로 사용하게 되고, 경고 메시지가 뜬다.

 

 


[key의 존재 유무에 따른 업데이트 방식]

map에 key 값이 없다면 중간의 값이 바뀌었을 때 그 하윗값들이 전부 변하기 때문이다.

key 값을 사용한다면 key를 이용해 중간의 값을 추가하게 된다.

 

<key가 없을 경우>

다음과 같은 배열 array가 있다.

배열 array

 

배열 array를 Element들로 변환하면 다음과 같은 결과가 나온다.

array.map(item => <div>{item}</div>);

array.map(item => <div>{item}</div>);의 결과


이때 array 배열에 b와 c 사이에 x를 삽입한다.

b와 c 가이에 x 삽입


배열에 x가 삽입된다면 당연히 새로운 div 태그가 삽입될 것으로 생각한다.


하지만 그렇지 않다.

<div> b </div> 와 <div> c </div> 사이에 새로운 태그가 생기는 것이 아닌 기존의 c가 z로 바뀌고 d는 c로, 맨 마지막에 d가 새로 삽입된다.

<div> c </div> 가 <div> x </div>로 바뀐다.


<div> d </div> 가 <div> c </div>로 바뀐다.


마지막으로 새로운 d가 생겨난다.

 


만약 배열 array에서 a를 삭제한다면 <div>a</div>만 없어지고 나머지는 그대로 있을 거라고 생각한다.

하지만 그렇지 않다.

<div>a</div>가 <div>b</div>로 바뀐다.


b가 x로 바뀐다.


x는 c로 바뀐다.


c는 d로 바뀐다.


마지막에 는 d가 없어진다.

 

키 값이 없다면 이러한 비효율적인 과정을 거치게 된다.

각 배열의 원소가 정확히 어떤 것을 렌더링 하고 있는지를 잘 모르기 때문이다.

단순히 자신이 n번째 원소인것만 알고 정확히 어떤 값을 렌더링 해야 하는지 모른다.

b가 삭제된다면 삭제되는것이 아닌 b가 x로 바뀌었다고 인식하게 된다.


<key가 있을 경우>

하지만 키가 있다면 달라진다.

고유 값이 있는 객체들이 있다. 이 고유 값을 key로 설정하게 되면 각 렌더링 한 결과물에서 정확히 어떤 객체를 가리키고 있는지 잘 알고 있다.

[
    {id:0, text:’a’},
    {id:1, text:’b’},
    {id:2, text:’c’},
    {id:3, text:’d’},
]

 


만약 {id:5,text:'x'}가 추가된다면 매우 효율적으로 업데이트된다.

b와 c 사이에 수정되지 않는 기존의 값은 그대로 두고 원하는 곳에 내용을 삽입할 수 있다. 


삭제 또한 마찬가지이다.

 


 

<정리>

  • 배열을 렌더링 하게 된다면 key를 설정해야 효율적으로 렌더링을 할 수 있다.
  • 고윳값이 없는 경우에 key라는 자리에 index값을 넣을 수 있긴 하지만 그것은 비효율적이다.
  • 다만 데이터가 몇 개 없을 경우, 자주 업데이트 되지 않는 경우 값을 index를 사용해도 문제가 되지는 않는다.
  • 배열 안의 값이 자주 업데이트되는데 key를 index로 사용하면 매우 비효율적으로 업데이트된다.

 

 


잘못된 정보는 댓글에 남겨주시면 감사하겠습니다!😊

댓글과 좋아요는 큰 힘이 됩니다!

 

 

728x90
반응형
Comments