[React] IterationCode

Sunki-Kim·2022년 11월 14일
0

React

목록 보기
1/7

웹 애플리케이션을 만들다보면 다음과 같이 반복되는 코드가 있기 마련이다.

import React from "react";

const IterationSample = () => {
  return (
    <ul>
      <li>눈사람</li>
      <li>얼음</li>
      <li></li>
      <li>바다</li>
    </ul>
  );
};

예를들면 다음 형태처럼 반복되는 리스트 코드같은 작업이 있다.

<li></li>

만약 보여줘야할 데이터가 유동적이라면, 결코 효율적인 코드라 보기 어렵고, 관리하는 측면에서 어려움이 생긴다.

이와 같은 IterationCode를 효율적으로 관리할 수 있는 방법을 알아보려한다.


javascript에서는 객체의 내장 함수인 map 함수를 활용하면, 반복되는 컴포넌트를 렌더링 할 수 있다.


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

export default IterationSample;

다음과 같이 원하는 렌더링 결과가 나온다.


하지만 key를 찾을수 없다는 에러가 있다.

map 형태를 띄는 컴포넌트 배열을 리액트에서 렌더링 할때는, 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;

다음과 같이 고유한 값이 없을떈, index를 넣어 리렌더링을 할 수 있지만, 비효율적이다.

데이터를 추가하는 과정을 고려하여, 코드를 작성해보려한다.

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

export default IterationSample;

다음 데이터가 배열에 추가되는 부분에 초기 작업을 진행했다.
useState로 상태를 설정하여, 이벤트를 실행할때 마다, 새로운 항목을 배열에 추가하려한다.

import React, { useState } from "react";

/**
 * ex 예제
 */

// const IterationSample = () => {
//   return (
//     <ul>
//       <li>눈사람</li>
//       <li>얼음</li>
//       <li>눈</li>
//       <li>바다</li>
//     </ul>
//   );
// };

/**
 * index key 설정
 */

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

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); // id값을 배열이 추가될때마다, 상태값이 더해준다.
    setNames(nextNames); // name 값을 업데이트 한다. (concat)
    setInputText(""); // 이벤트가 작동하면, input을 비워준다.
  };

  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;

click 이벤트에 concat을 넣어 상태값을 업데이트를 해준다.
id와 name을 추가해주는 상태를 주입해준다.

리액트에서는 상태를 업데이트 할때, 기존 상태를 그대로 두면서 새로운 값을 상태로 설정하는 불변성 유지 해준다. 이같이 불변성 유지를 해줘야 성능이 최적화가 된다.

소스코드

profile
당신에게 가치있는 Developer가 되고자

0개의 댓글