[React] List와 Key

문지은·2023년 7월 16일
0

React

목록 보기
9/24
post-thumbnail

배열

  • 배열(Array)
    • 자바스크립트의 변수나 객체를 하나의 변수로 묶어놓은 것
    • 예 : const numbers = [1, 2, 3, 4, 5];

여러 개의 컴포넌트 렌더링하기

  • 같은 컴포넌트를 화면에 반복적으로 나타내야 할 경우에 이를 코드에 하나씩 직접 넣는 것은 매우 비효율적
  • map() 함수를 사용하여 해결할 수 있다.
    • 배열에 들어있는 각 변수에 어떤 처리를 한 뒤 리턴하는 것
    • 예를 들어 map() 함수를 사용하여 numbers 배열에 들어있는 각 숫자에 2를 곱한 값이 들어간 doubled의 배열을 생성해보면 다음과 같다.
      const doubled = numbers.map((number) => number * 2);

실제로 리액트에서 map() 함수를 사용해보자.

  • 숫자 1부터 5까지 들어 있는 numbers 배열을 map() 함수를 사용하여 <li> 태그로 감싸 리턴한다.
const numbers = [1, 2, 3, 4, 5];

const listItems = numbers.map((number) =>
    <li>{number}</li>
);
  • 작성한 코드를 화면에 렌더링 하기 위해 아래와 같이 코드를 작성한다.
ReactDOM.render(
    <ul>{listItems}</ul>,
    document.getElementById('root')
);
  • 결과적으로 listItems 배열을 아래와 같이 <ul> 태그로 감싸서 렌더링 하게 된다.
ReactDOM.render(
    <ul>
        <li>{1}</li>
        <li>{2}</li>
        <li>{3}</li>
        <li>{4}</li>
        <li>{5}</li>
    </ul>,
    document.getElementById('root')
);
  • 실행 결과

기본적인 리스트 컴포넌트

  • 위에서 작성한 코드를 별도의 컴포넌트로 분리해보자.
function NumberList(props) {
    const { numbers } = props;

    const listItems = numbers.map((number) =>
        <li>{number}</li>
    );

    return (
        <ul>{listItems}</ul>
    );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
    <NumberList numbers={numbers} />,
    document.getElementById('root')
);
  • NumberList 컴포넌트는 props로 숫자가 들어있는 배열인 numbers를 받아서 이를 목록으로 출력한다.
  • 하지만 현재 각 아이템에 아직 키가 없기 때문에 콘솔창에는 리스트 아이템에는 무조건 키가 있어야 한다는 경고 문구가 출력된다.

키(Key)

  • 키(Key)
    • 리스트에서 아이템을 구분하기 위한 고유한 문자열
    • 리스트에서 어떤 아이템이 변경, 추가 또는 제거되었는지 구분하기 위해 사용
  • 리액트에서의 키의 값은 같은 리스트에 있는 엘리먼트 사이에서만 고유한 값이면 된다.

키 값으로 숫자의 값 사용하기

  • 아래처럼 numbers 배열의 숫자들이 중복되지 않은 경우에는 정상적으로 작동하지만,
  • 만약 numbers 배열에 중복된 숫자가 들어있다면 키 값도 중복되기 때문에 고유해야한다는 키값의 조건이 충족되지 않음
const numbers = [1, 2, 3, 4, 5];

const listItems = numbers.map((number) =>
    <li key={number.toString()}>
        {number}
    </li>
);
  • 키값 지정시 경고 메시지 없어짐

  • 키값이 중복되었을 경우 경고메시지 출력

키값으로 id 사용하기

  • id의 의미 자체가 고유한 값이라는 것이기 때문에 키값으로 사용하기에 적합
  • id가 있는 경우 보통 id 값을 키값으로 사용
const todoItems = todos.map((todo) => {
    <li key={todo.id}>
        {todo.text}
    </li>
});

키값으로 index 사용하기

  • map() 함수에서 두 번째 파라미터로 제공해주는 인덱스 값을 키값으로 사용
  • 인덱스도 고유한 값이기 때문에 키값으로 사용해도 되지만 배열에서 아이템의 순서가 바뀔수 있는 경우에는 사용하면 안됨
  • 리액트에서는 키를 명시적으로 넣어주지 않으면 기본적으로 인덱스 값을 키값으로 사용
const todoItems = todos.map((todo, index) => {
  	// 아이템의 고유한 ID 가 없을 경우에만 사용
    <li key={index}>
        {todo.text}
    </li>
});

실습 - 출석부 출력하기

출석부 컴포넌트 만들기

// src/chapter_10/AttendancdBook.jsx

import React from "react";

const students = [
    {
        name: "Inje",
    },
    {
        name: "Steve",
    },
    {
        name: "Bill",
    },
    {
        name: "Jeff",
    },
];

function AttendanceBook(props) {
    return (
        <ul>
            {students.map((student) => {
                return <li>{student.name}</li>;
            })}
        </ul>
    );
}

export default AttendanceBook;
  • index.js 파일 수정 후 애플리케이션 실행
// src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import AttendanceBook from './chapter_10/AttendanceBook';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <AttendanceBook />
  </React.StrictMode>
);

reportWebVitals();
  • 실행 결과
    • 화면에 학생들의 이름이 목록 형태로 출력되지만 키가 없다는 경고 메시지 출력

id 추가하기

  • 각 해당 객체에 고유한 값을 가진 id를 추가해주고 map() 함수 엘리먼트에 key={student.id} 넣어주기
import React from "react";

const students = [
    {
        id: 1,
        name: "Inje",
    },
    {
        id: 2,
        name: "Steve",
    },
    {
        id: 3,
        name: "Bill",
    },
    {
        id: 4,
        name: "Jeff",
    },
];

function AttendanceBook(props) {
    return (
        <ul>
            {students.map((student) => {
                return <li key={student.id}>{student.name}</li>;
            })}
        </ul>
    );
}

export default AttendanceBook;
  • 경고문구가 사라진 것을 볼 수 있다.

  • 위에서 배운 것처럼 키 값은 아래와 같이 다양한 방식으로 사용할 수도 있다.
// id를 키 값으로 사용
{students.map((student) => {
    return <li key={student.id}>{student.name}</li>;
})}

// 포맷팅 된 문자열을 키값으로 사용
{students.map((student, index) => {
    return <li key={`student-id-${student.id}`}>{student.name}</li>;
})}

// 배열의 인덱스를 키값으로 사용
{students.map((student, index) => {
    return <li key={index}>{student.name}</li>;
})}

실습 전체 코드

References

profile
코드로 꿈을 펼치는 개발자의 이야기, 노력과 열정이 가득한 곳 🌈

2개의 댓글

comment-user-thumbnail
2023년 7월 31일

기본적인 부분 공부 잘 하고 가요. 진짜 선생님은 최고입니다 :)

1개의 답글