차곡차곡

[React] #6 컴포넌트 반복 본문

Web programming/React

[React] #6 컴포넌트 반복

sohy 2022. 7. 6. 13:41

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

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

 

arr.map(callback, [thisArg])

  • callback: 새로운 배열의 요소를 생성하는 함수로 파라미터는 다음 세 가지가 있다.
    • currentValue: 현재 처리하고 있는 요소
    • index: 현재 처리하고 있는 요소의 index 값
    • array: 현재 처리하고 있는 원본 배열
  • thisArg(선택 항목): callback 함수 내부에서 사용할 this 레퍼런스
// 배열 요소를 제곱하여 새로운 배열 생성

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

 

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

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

>> 결과는 잘 렌더링 되지만 콘솔창을 열어보면 "Key" prop이 없다는 경고 메시지가 뜬 걸 확인할 수 있다. 리액트에서 key는 컴포넌트 배열을 렌더링했을 때 어떤 원소에 변동이 있었는지 알아내기 위해 사용한다. 

 

key 설정

key 값 설정은 map 함수의 인자로 전달되는 함수 내부에서 컴포넌트 props를 설정하듯이 설정한다. key 값은 언제나 유일해야 하기 때문에 데이터가 가진 고윳값을 key 값으로 설정해야 한다. 고유 번호가 없을 때는 콜백 함수의 인수인 index 값을 활용한다. 하지만 Index를 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;

 

 

데이터 추가 기능 구현하기

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 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;

* 배열에 새 항목을 추가할 때 배열의 push 함수를 사용하지 않고 concat을 사용하였는데, push함수는 기존 배열 자체를 변경해 주는 반면 concat은 새로운 배열을 만들어 준다는 차이점이 있다. 리액트에서 상태를 업데이트할 때는 기존 상태를 그대로 두면서 새로운 값을 상태로 설정해야 한다. 이를 불변성 유지라고 한다. 불변성 유지를 해 주어야 나중에 리액트 컴포넌트의 성능을 최적화할 수 있다. 

 

데이터 제거 기능 구현하기

불변성을 유지하면서 배열의 특정 항목을 지울 때는 배열의 내장 함수 filter를 사용한다. filter 함수의 인자에 분류하고 싶은 조건을 반환하는 함수를 넣어주면 배열에서 특정 조건을 만족하는 원소들만 쉽게 분류할 수 있다.

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

const numbers = [1, 2, 3, 4, 5, 6];
const withoutThree = numbers.filter(number => number != = 3);
// 결과: [1, 2, 4, 5, 6]
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;

 

 

상태 안에서 배열을 변형할 때는 배열에 직접 접근하여 수정하는 것이 아니라 concat, filter등의 배열 내장 함수를 사용하여 새로운 배열을 만든 후 이를 새로운 상태로 설정해 주어야 한다!

 

 

참고 자료 : https://thebook.io/080203/

 

 

'Web programming > React' 카테고리의 다른 글

[React] #7 Hooks (1)  (4) 2022.07.11
[React/실습] 투두리스트 제작 #2  (0) 2022.07.07
[React] #5 이벤트 핸들링  (3) 2022.07.06
[React] #4 state  (0) 2022.07.06
[React/실습] 투두리스트 제작 #1  (7) 2022.07.05
Comments