컴포넌트 반복

정재성·2022년 5월 22일
0
post-thumbnail

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

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

문법

arr.map(callback , [thisArg])텍스트

  • callback:새로운 배열의 요소를 생성하는 함수로 파라미터는 다음 세가지이다
    • currentValue:현재처리하고있는 요소
    • index현재 처리하고있는 요소의 Index값
    • array:현재 처리하고있는 원본 배열
  • thisArg: callback함수 내부에서 사용할 레퍼런스

예제

const numbers = [1,2,3,4,5];
const result = numbers.map(num => num*num);
console.log(result)
///[1,4,9,16,25]

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

위랑 똑같은 원리로 기존 배열로 컴포넌트로 구성된 배열을 생성 할 수도 있다.


const IternationSample = () => {
  const names = ["눈사람", "얼음", "눈", "바람"];
  const nameList = names.map((name) => <li>{name}</li>);
  return <ul>{nameList}</ul>;
};
export default IternationSample;
//해당 컴포넌트를  app.js 에 연결해서 실행 시키면 'key'값이 없다고 뜬다.

3.key 값 설정

리액트에서 key는 컴포넌트 배열을 렌더링했을때 어떤 원소에 변동이 있었는지 알아내려고 사용한다.
key값이 있다면 그 요소에 어떤 변화가 일어났는지 빠르게 알수있다.

key값은 데이터가 가진 고윳값을 key로 설정해야한다.

앞서 만든 예제는 이런 고유 번호가 없다.
이때는 map함수에 전달되는 콜백함수의 인수인 index값을 사용한다

const IternationSample = () => {
 const names = ["눈사람", "얼음", "눈", "바람"];
 const nameList = names.map((name, index) => <li key={index}>{name}</li>);
		///고유한 값인 인덱스로 키값을 주면 해당컴포넌트는 경고메세지가 사라지는걸 볼수 있다.
 return <ul>{nameList}</ul>;
};
export default IternationSample;

고유한 값이 없을떄만 key로 index를 사용해야한다.

index를 key로 사용하면 배열이 변경될때 효율적으로 렌더링 하지 못하기 떄문.

4.응용

import { useState } from "react";

const IternationSample = () => {
  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 nameList = names.map((name) => <li key={name.id}>{name.text}</li>);
  return <ul>{nameList}</ul>;
};
export default IternationSample;

예제를 다음과 같이 수정해본 결과 , 브라우저에 이전과 같은 결과가 나옴.
이번에는 map함수를 사용할때 key값을index대신 name.id로 지정해주었다.

데이터 추가기능 구현하기

이제 새로운 이름을 등록할 수 있는 기능을 구현해보자.
ul태그 상단에 input , button을 렌더링하고 input의 상태를 관리해보았다.

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

그 다음으로 버튼을 클릭했을때 호출할 onClick함수를 선언하여 onClick이벤트로 설정하였다.

const IternationSample = () => {
  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);//nextId값에 1을 더해준다
    setNames(nextNames);//names 값을 업데이트한다
    setInputText("");//InputText를 비운다.
  };

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

배열에 새항목을 추가할때 push 대신 concat을 사용했다 pusy와 concat의 차이는 기존 상태를 그냥 두냐 변하게하느냐의 차이이다 리액트에서는 상태를 업데이트시 기존상태를 그대로 두면서 새로운 값의 상태로 설정해야한다. (불변성 유지)

onClick함수에서 새로운 항목을 추가할떄 객체의 id값은 nextId를 사용하도록하고 , 클릭될떄마다 1씩 올라가도록 구현했다. 또한 button이 클릭될때 기존의 input 내용이 비워지도록 구현했다.

profile
기술블로그 / 일상블로그

0개의 댓글