[React] 리액트를 다루는 기술 - 6장 컴포넌트 반복

Lynn·2021년 8월 10일
0

React

목록 보기
9/17
post-thumbnail

자바스크립트 배열의 map() 함수

map 함수는 파라미터로 전달된 함수를 사용해서 배열 내 각 요소를 원하는 규칙에 따라 변환한 후 그 결과로 새로운 배열을 생성한다.
arr.map(callback, [thisArg])

  • callback: 새로운 배열의 요소를 생성하는 함수
  • thisArg(필수 X): callback 함수 내부에서 사용할 this 레퍼런스

아래는 예제 코드로, processed[1, 4, 9, 16, 25] 배열이 저장된다.

var numbers = [1, 2, 3, 4, 5];
var processed = numbers.map(num => num*num);

데이터 배열을 컴포넌트 배열로 변환할 수도 있다.

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

하지만 위 코드를 브라우저에서 렌더링하면 key가 없다는 warning이 뜬다. 이를 해결하려면?

리액트에서는 컴포넌트 배열을 렌더링했을 때 어떤 원소에 변동이 있었는지 알아내기 위해 key를 사용한다. 예를 들어 원소를 새로 생성하거나 제거, 수정할 때 key가 없다면 Virtual DOM에서 리스트를 순차적으로 비교하면서 변화를 감지하지만 key가 있다면 더욱 빠르게 알아낼 수 있다.

key 값은 유일해야 하기 때문에 데이터가 가진 고윳값으로 설정해야 한다. 데이터의 고윳값이 딱히 없다면 map 함수에 전달되는 콜백 함수의 인수인 index 값을 사용할 수도 있다.

const IterationSample = () => {
  const names = ['눈사람', '얼음', '눈', '바람'];
  const nameList = names.map((name, index) => <li key={index}>{name}</li>);
  return <ul>{nameList}</ul>;
};

응용

데이터 배열에서 새로운 항목을 추가할 때 사용할 고유 id를 위한 state 또한 만들어줬다.

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 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 onRemove = id => {
    const nextNames = names.filter(name => name.id !== id);
    setNames(nextNames);
  };
  const namesList = names.map(name => (
    <li key={name.id} onDoubleClick={() => onRemove(name.id)}>
      {name.text}
    </li>
  ));
  return (
    <>
      <input value={inputText} onChange={onChange} />
      <button onClick={onClick}>추가</button>
      <ul>{namesList}</ul>
    </>
  );
};

export default IterationSample;

데이터 제거 기능에서 쓰인 배열의 내장 함수 filter의 기능만 짚고 넘어가겠다. filter 함수의 인자에 분류하고 싶은 조건을 반환하는 함수를 넣어 주면 쉽게 분류할 수 있다.

사용 예시

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

0개의 댓글