코딩하는라민

[React] 리스트(배열) 렌더링, Key 본문

Core/React

[React] 리스트(배열) 렌더링, Key

코딩하는라민 2023. 2. 26. 00:57
728x90
반응형

[React] 리스트(배열) 렌더링, Key

 

📌 JS 에서 리스트를 반환하는 방법

const arr = [1, 2, 3];
const arrChange = arr.map((arr) => arr + 1);

console.log(arr, arrChange);

콘솔창

map 함수는 배열 안의 요소로 새로운 배열을 반환한다.

원본을 변형하지 않는다.

 

리액트에서도 자바스크립트에서처럼 리스트를 반환하는 방법은 비슷하다!

리액트에서는 map 함수를 이용해 리액트 엘리먼트를 반환하면 된다.

 

 

Array.prototype.map() - JavaScript | MDN

map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다.

developer.mozilla.org

 

📌 리액트에서 map 함수 사용하여 리스트 동적 렌더링하기

import React from 'react';
import './style.css';

export default function App() {
  const number = ['eat', 'sleep', 'study'];
  const myList = number.map((number) => <li>{number}</li>);

  return <ul>{myList}</ul>;
}

Shantell Sans 폰트(구글폰트)

 

 

이대로 끝난 것이 아니다.

리액트에서는 배열을 렌더링하려면 key 라는 속성을 추가해줘야한다.

key 를 넣지 않은 경우에는 콘솔창에서 경고가 뜰 것이다.

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

 

📌 Key

Key는 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕는다.

 

💡 왜 Key 가 필요한 것일까?

JSX 를 이용해서 아래와 같은 리스트를 렌더링한다고 해보자.

<ul>
    <li>1. HTML</li>
    <li>2. CSS</li>
    <li>3. Javscript</li>
</ul>

만약 ul의 제일 마지막 자식으로 리스트를 추가해야 한다면 리액트에서는 위에서부터 차례대로 변경사항이 있는지 없는지 추적하고, 마지막 요소에 변경사항이 있는 것을 확인하고 항목을 추가할 것이다.

<ul>
    <li>1. HTML</li>
    <li>2. CSS</li>
    <li>3. Javscript</li>
    <li>4. React</li>
</ul>

그런데

만약 리스트의 제일 첫번 째에 항목을 추가해야한다면?

<ul>
    <li>Web Developer</li>
    <li>1. HTML</li>
    <li>2. CSS</li>
    <li>3. Javscript</li>
    <li>4. React</li>
</ul>

첫번째 항목부터 변경사항으로 파악하고 이를 업데이트할 것이다.

즉 이러한 과정은 굉장히 비효율적인 것이다.

 

이러한 문제를 해결하기 위해서 " Key " 를 사용하는 것이다.

자식들이 Key 를 가지고 있다면, Key 를 기준으로 변경사항 전과 변경사항 이후의 자식들이 일치하는지 확인한다. 

따라서 위의 예제에서 제일 위에 리스트 항목을 추가한다면, 변경사항이 있는 요소만 추가될 뿐 기존에 있던 나머지 항목들은 '이동'만 하게 되는 것이다.

<ul>
    <li key="0">Web Developer</li>
    <li key="1">1. HTML</li>
    <li key="2">2. CSS</li>
    <li key="3">3. Javscript</li>
    <li key="4">4. React</li>
</ul>

 

 

재조정 (Reconciliation) – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

📌 Key 로 어떤 값을 넣으면 좋을까?

key 는 각 엘리먼트들이 가지고 있는 고유값으로 설정한다.

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

<li key={Home.id}>

 

가장 좋은 방법은 리스트의 다른 항목들 사이에서 해당 항목을 고유하게 식별할 수 있는 문자열을 사용하는 것이다.

엘리먼트들은 고유한 식별자를 가지고 있고, 해당 데이터를 key 값으로 받을 수 있다.

 

Key 로 활용할 수단이 없다면 리스트의 인덱스를 Key 로 받을 수 있다.

<li key={index}></li>

하지만 이 방법은 정말 최후의 수단으로만 사용해야한다.

모든 항목이 재배열될 경우가 아니라면 비효율적일 수 있기 때문이다.

간단하게 말해서 항목의 순서가 바뀔 수 있는 경우는 Key 로 index 를 사용하는 경우는 부정적인 영향을 초래할 수 있기 때문에 권장하지 않는다.

 

✅ Key 는 배열 안에서 사용해야한다.

Key 는 map() 함수 내부의 엘리먼트에서 사용해야한다.

 

✅ Key 는 형제 사이에서만 유일하면 된다.

Key 는 전역에서 유일할 필요는 없고, 리스트를 구분하는 목적이므로 형제 사이에서만 유일하면 된다.

두 개의 다른 배열을 만든다고 한다면, 동일한 key 를 사용해도 무방하다.

import React from 'react';
import './style.css';

export default function App(props) {
  const master = [
    {id: 1, lang: 'JavaScript', add: 'HTML+CSS'},
    {id: 2, lang: 'React', add: 'JavScript+JSX'}
  ]
  const List1 = master.map((master) => <li key={master.id}>{master.lang}</li>);

  const List2 = master.map((master) => <li key={master.id}>{master.add}</li>);

  return <>
    <div className="firstList">
      {List1}
    </div>
    <div className="secondList">
      {List2}
    </div>
  </>;
}

 

✅ JSX 에 map 함수를 포함시킬 수도 있다.

import React from 'react';
import './style.css';

export default function App(props) {
  const master = [
    {id: 1, lang: 'JavaScript', add: 'HTML+CSS'},
    {id: 2, lang: 'React', add: 'JavScript+JSX'}
  ]
  return <>
    <div className="firstList">
      {master.map((master) => <li key={master.id}>{master.lang}</li>)}
    </div>
    <div className="secondList">
      {master.map((master) => <li key={master.id}>{master.add}</li>)}
    </div>
  </>;
}

JSX 내부에는 표현식을 쓸 수 있다.

문이 아닌 map 함수의 결과를 인라인으로 처리할 수도 있다.

 

 

 

 

List(arr) Lendering - map, key - StackBlitz

A create-react-app project based on react and react-dom.

stackblitz.com

 

 


참고 : 리액트 공식 문서
  등을 공부하고, 간단하게 정리한 내용입니다. 잘못된 부분이나 문제되는 점이 있으면 댓글 부탁드립니다.

728x90
반응형

'Core > React' 카테고리의 다른 글

[React] Hooks - useState ( )  (0) 2023.03.05
[React] form 제어하기  (0) 2023.02.28
[React] 조건부 렌더링  (0) 2023.02.25
[React] state 와 setState() - 클래스형 컴포넌트  (0) 2023.02.25
[React] 이벤트 처리하기  (0) 2023.02.22