[React Basic] 컴포넌트 반복하기

Joah·2022년 9월 26일
0

React Basic

목록 보기
23/25

게시글은 리액트 공부용이며 출처를 제시합니다.
출처: 소플의 처음 만난 React, 리액드를 다루는 기술, 모던 자바스크립트 deep dive

컴포넌트 반복 iteration

리액트에서 반복적인 내용을 효율적으로 보여 주고 관리하는 방법


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

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

import React from "react";

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

export default IterationSample;

📍"key" props가 없다는 에러... key는 뭘까?

리액트에서 key는 컴포넌트 배열을 렌더링했을 때 어떤 원소에 변동이 있었는지 알아내려고 사용한다.
유동적인 데이터를 다룰 때는 원소를 새로 생성할 수도, 제거할 수도, 수정할 수도 있다.
key가 없을 때는 Virtual DOM을 비교하는 과정에서 리스트를 순차적으로 비교하면서 변화를 감지한다.

하지만 key 가 있다면 이 값을 사용하여 어떤 변화가 일어났는지 더욱 빠르게 알아낼 수 있다.

key 설정

key값을 설정할 때는 map 함수의 인자로 전달되는 함수 내부에서 컴포넌트 props를 설정하듯이 설정하면 된다. key값은 언제나 고유해야 하며 데이터가 가진 고윳값을 key값으로 설정해야 한다.

import React from "react";

const IterationSample = () => {
  const name = ["눈사람", "얼음", "눈", "바람"];
  return (
    <div>
      {name.map((name) => (
        <div key={name}>
          <li>{name}</li>
        </div>
      ))}
    </div>
  );
};

export default IterationSample;

만약 index를 key값으로 설정하게 되면 배열이 변경될 때 효율적으로 리렌더링을 하지 못한다. 따라서 new Date() 메서드로 id값을 지정하곤 한다.


🛼 동적인 배열 렌더링하기

📍 데이터 추가 기능 구현

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 = (e) => {
    //push는 기존 배열 자체를 변경하지만 concat은 새로운 배열을 만들어준다.
    const nextNames = names.concat({
      id: nextId,
      text: inputText,
    });
    //이전에 반환된 id 값에 1씩 더하면 id 값이 1씩 증가하여 겹치지 않는다.
    setNextId(nextId + 1);
    //원래 데이터에 새로 생성한 배열 데이터로 업데이트 한다.
    setNames(nextNames);
    //onClick하고 input창을 비워준다.
    setInputText("");
  };

  const nameList = names.map((name) => <li key={name.id}>{name.text}</li>);

  return (
    <div>
      <input value={inputText} onChange={onChange} />
      <button onClick={onClick}>추가</button>
      <ul>{nameList}</ul>
    </div>
  );
};

export default IterationSample;

📍 데이터 제거 기능 구현

각 항목을 더블클릭했을 때 해당 항목이 화면에서 사라지는 기능
불변성을 유지하면서 업데이트 하는 것이 포인트
불변성을 유지하면서 배열의 특정 항목을 지울때는 배열의 내장 함수 filter를 사용한다.

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

  const onRemove = (id) => {
    //불변성을 지키기 위해 새로운 배열을 만들어서 filtering된 결과를 할당
    const removedData = names.filter((name) => id !== name.id);
    setNames(removedData);
  };

  const nameList = names.map((data) => (
    //매핑으로 인해 onRemove 함수의 인자로 클릭되는 요소의 id 값을 가져오기, 
    //각각의 li 태그를 클릭할 것이기 때문에 onDoubleClick 부여하기 
    <li key={data.id} onDoubleClick={() => onRemove(data.id)}>
      {data.text}
    </li>
  ));

  return (
    <div>
      <input value={inputText} onChange={onChange} />
      <button onClick={onClick}>추가</button>
      <ul>{nameList}</ul>
    </div>
  );
  • onDoubleClick 메서드는 기본적으로 제공되는 메서드이며 더블클릭이 일어났을 때의 이벤트를 정의하면 된다.

🛼 정리

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

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

profile
Front-end Developer

0개의 댓글