본문 바로가기
Frontend/ReactJS(완)

React - 6장 : 컴포넌트 반복

by 리키이 2023. 2. 13.

6-1. 자바스크립트 배열의 map() 함수

- 자바스크립트 배열 객체의 내장 함수인 map 함수를 사용하여 반복되는 컴포넌트를 렌더링할 수 있다. 

- map 함수는 파라미터로 전달된 함수를 사용해서 배열 내 각 요소를 원하는 규칙에 따라 변환한 후 그 결과로

  새로운 배열을 생성한다.

 

1) 문법

// 기본문법
arr.map(callback, [thisArg])

// 예제
const numbers = [1, 2, 3, 4, 5];
const result = numbers.map(num => num * num);
console.log(result);

- callback : 새로운 배열의 요소를 생성하는 함수로 파라미터는 다음 세가지

     - currentValue : 현재 처리하고 있는 요소

     - index : 현재 처리하고 있는 요소의 index 값

     - array : 현재 처리하고 있는 원본 배열

- thisArg : callback 함수 내부에서 사용할 this 래퍼런스

 

6-2. 데이터 배열을 컴포넌트 배열로 변환하기

- 문자열로 구성된 배열을 선언하고 그 배열 값을 사용하여 <li>…</li> JSX 코드로 된 배열을 새로 생성한 후 

   nameList에 담는다.

import React from 'react';
 
const IterationSample = () => {
  const names = ['눈사람', '얼음', '눈', '바람'];
  const nameList = names.map(name => <li>{name}</li>);
  return <ul>{nameList}</ul>;
};
 
export default IterationSample;

 

6-3. Key

- 리액트에서 key는 컴포넌트 배열을 렌더링했을 때 어떤 원소에 변동이 있었는지 알아내려고 사용한다.

- 유동적인 데이터를 다룰 때는 원소를 새로 생성할 수도, 제거할 수도, 수정할 수도 있다.

key가 없을 때는 Virtual DOM을 비교하는 과정에서 리스트를 순차적으로 비교하면서 변화를 감지한다.

 

1) key 설정

- key 값을 설정할 때는 map 함수의 인자로 전달되는 함수 내부에서 컴포넌트 props를 설정하듯이 설정하면 된다.

- key 값은 언제나 유일해야 한다.

- 데이터가 가진 고윳값을 key 값으로 설정해야 한다.

- map 함수에 전달되는 콜백 함수의 인수인 index 값을 사용하여 key값을 설정하면 key값이 없을때 나오는

  에러가 나오지 않는다.

 

import React from 'react';
 
const IterationSample = () => {
  const names = ['눈사람', '얼음', '눈', '바람'];
  const namesList = names.map((name, index) => <li key={index}>{name}</li>);
  return <ul>{namesList}</ul>;
};
 
export default IterationSample;

 

6-4. 응용

1) 초기상태 설정

-  map 함수를 사용할 때 key 값을 index 대신 name.id 값으로 지정

 

import React, { useState } from 'react';
 
const IterationSample = () => {
  const [names, setNames] = useState([
    { id: 1, text: '눈사람' },
    { id: 2, text: '얼음' },
    { id: 3, text: '눈' },
    { id: 4, text: '바람' }
  ]);
  const [inputText, setInputText] = useState('');
  const [nextId, setNextId] = useState(5); // 새로운 항목을 추가할 때 사용할 id
 
  const namesList = names.map(name => <li key={name.id}>{name.text}</li>);
  return <ul>{namesList}</ul>;
};
 
export default IterationSample;

 

2) 데이터 추가기능 구현

- concat으로 불변성 유지 

- push 함수는 기존 배열 자체를 변경해 주는 반면, concat은 새로운 배열을 만들어 준다는 차이점이 있다.

 

import React, { useState } from 'react';
 
const IterationSample = () => {
  ...(생략)
 
  const onChange = e => setInputText(e.target.value);
  const onClick = () => {
    const nextNames = names.concat({
      id: nextId, // nextId 값을 id로 설정하고
      text: inputText
    });
    setNextId(nextId + 1); // nextId 값에 1을 더해 준다.
    setNames(nextNames); // names 값을 업데이트한다.
    setInputText(''); // inputText를 비운다.
  };
 
  const namesList = names.map(name => <li key={name.id}>{name.text}</li>);
  return (
    <>
      <input value={inputText} onChange={onChange} />
      <button onClick={onClick}>추가</button>
      <ul>{namesList}</ul>
    </>
  );
};
 
export default IterationSample;

 

3) 데이터 제거 기능 구현하기

- filter 함수를 사용하면 배열에서 특정 조건을 만족하는 원소들만 쉽게 분류가능

 

const numbers = [1, 2, 3, 4, 5, 6];
const biggerThanThree = numbers.filter(number => number > 3);
// 결과: [4, 5, 6]

 

- 구현

  - map을 통해 name.id를 key 로 가지고 있는 DOM에 onRemove 함수 설정

  - filter가 불변성 유지가 되기 때문에 concat, spread 쓸 필요 없음.

 

...(생략)

const onRemove = id => {
    const nextNames = names.filter(name => name.id != = id);
    setNames(nextNames);
  };
  
  const nameList = names.map((name) => {
    return (
    <li key={name.id} onDoubleClick={() => onRemove(name.id)}>
        {name.text}
    </li>
    );
});

댓글