FRONT-END/REACTJS

컴포넌트 반복

JINGMONG 2021. 12. 26. 05:24

웹 어플리케이션을 만들다 보면 반복되는 코드를 작성할 때가 있다.

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

자바스크립트 배열 객체의 내장 함수인 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);
console.log(result);

map 함수는 기존 배열로 새로운 배열을 만드는 역할

데이터 배열을 컴포넌트 배열로 변환

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

export default IterationSample;
import { Component } from 'react';
import IterationSample from './IterationSample';

class App extends Component {
  render() {
    return <IterationSample />;
  }
}

export default App;

Key

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

원소를 새로 생성할 수도, 제거할 수도, 수정할 수도 있다. key가 없을 때는 Virtual DOM을 비교하는 과정에서 리스트를 순차적으로 비교하면서 변화를 감지, key가 있다면 이 값을 사용하여 어떤 변화가 일어났는지 알아낼 수 있다

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

export default IterationSample;

컴포넌트 배열을 렌더링 할 때는 key 값 설정에 항상 주의를 해야한다. key값은 언제나 유일해야한다. key값이 중복된다면 렌더링 과정에서 오류가 발생한다.

데이터 추가 기능 구현

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

  const onChange = (e) => setInputText(e.target.value);
  const onClick = () => {
    const nextNames = names.concat({
      id: nextId,
      text: inputText,
    });
    setNextId(nextId + 1);
    setNames(nextNames);
    setInputText('');
  };

  const nameList = names.map((name) => <li key={name.id}>{name.text}</li>);
  return (
    <>
      <input value={inputText} onChange={onChange} />
      <button onClick={onClick}>추가</button>
      <ul>{nameList}</ul>;
    </>
  );
};

export default IterationSample;

불변성 유지

배열에 새 항목을 추가할 때 배열의 push 함수를 사용하지 않고 concat을 사용함, push함수는 기존 배열 자체를 변경해 주는 반면, concat은 새로운 배열을 만들어 준다는 차이가 있다.

리액트에서는 상태를 업데이트할 때는 기존 상태를 그대로 두면서 새로운 값을 상태로 설정해야 한다. 이를 불변성 유지라고 한다. 불변성 유지를 해 주어야 리액트 컴포넌트의 성능을 최적화 할 수 있다.

데이터 제거 기능 구현

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

  const onChange = (e) => setInputText(e.target.value);
  const onClick = () => {
    const nextNames = names.concat({
      id: nextId,
      text: inputText,
    });
    setNextId(nextId + 1);
    setNames(nextNames);
    setInputText('');
  };

  const onRemove = (id) => {
    const nextNames = names.filter((name) => name.id !== id);
    setNames(nextNames);
  };

  const nameList = 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>{nameList}</ul>;
    </>
  );
};

export default IterationSample;

마찬가지로 데이터를 제거할 때에도 불변성을 유지하면서 업데이트 해주어야 한다. 불변성을 유지하면서 데이터를 지울 때는 배열의 내장 함수 filter를 사용한다.

filter 함수를 사용하면 배열에서 특정 조건을 만족하는 원소들만 쉽게 분류할 수 있다.

'FRONT-END > REACTJS' 카테고리의 다른 글

라이프사이클 메서드  (0) 2021.12.28
컴포넌트의 라이프사이클  (0) 2021.12.28
컴포넌트에 ref 달기  (0) 2021.12.24
ref 사용  (0) 2021.12.24
ref를 사용하는 상황  (0) 2021.12.24