📖 리액트/리액트를 다루는 기술

6강 컴포넌트 반복

놀러와요 버그의 숲 2022. 1. 24. 08:20
728x90
반응형

이 글은 『리액트를 다루는 기술』(개정판/ 김민준 저 / 길벗 출판사)이라는 책을 참고하여 썼습니다.

 

학습 범위:  p158 ~p.170

 

 

6.2.1  예제를 하면서 실수를 하였다.

 

.map()함수를 이용해서 <li> </li>를 반복적으로 렌더링해주는 예제였는데, 실수로 fashion을 {}로 안치니까 그냥 fashion 글자

그대로 렌더링이 되어서 당황하였다.

 

올바른 코드는 다음 아래와 같다.

const IterationSample = () => {
  const data = ["스트릿", "아메카지", "캐쥬얼", "데님", "포멀"];
  const dataList = data.map((fashion, index) => <li key={index}>{fashion}</li>);
  // 여기서 그냥 {}쓰지 않고, <li>fashion</li> 해버리면 fashion이라는 글자만 반복된다.

  return <ul>{dataList}</ul>;
};

export default IterationSample;

 

 

6.4.1 초기 상태 설정하기

 

import { useState } from "react";

const IterationSample = () => { 
 
 // 데이터배열
  const [brandName, setBrandName] = useState([
    { id: 1, brand: "Addidas" },
    { id: 2, brand: "Nike" },
    { id: 3, brand: "New Balance" },
    { id: 4, brand: "Vans" },
  ]);
  //   텍스트 입력할 수 있는 input의 상태
  const [userInp, setUserInp] = useState("");
  // 데이터 배열에서 새로운 항목을 추가할 때 사용할 고유 id를 위한 상태
  const [nextId, setNextId] = useState(5);

  const brandList = brandName.map((item) => (
    <li key={item.id}>{item.brand}</li>
  ));
  return <ul>{brandList}</ul>;
};

export default IterationSample;

 

 

6.4.2  데이터 추가 기능 구현

 

import { useState } from "react";

const IterationSample = () => { 
 
 // 데이터배열
  const [brandName, setBrandName] = useState([
    { id: 1, brand: "Addidas" },
    { id: 2, brand: "Nike" },
    { id: 3, brand: "New Balance" },
    { id: 4, brand: "Vans" },
  ]);


//   텍스트 입력할 수 있는 input의 상태
  const [userInp, setUserInp] = useState("");
  // 데이터 배열에서 새로운 항목을 추가할 때 사용할 고유 id를 위한 상태
  //   4개까지 만들었으니 다음 id가 5부터 오게 설정
  const [nextId, setNextId] = useState(5);

  //  input의 value를 업데이트
  const onChange = (event) => {
    setUserInp(event.target.value);
  };
  const onClick = () => {
    //   concat을 사용하여 새로운 항목을 추가한 배열을 만들고, setBrandName을 통해 상태 업데이트
    const nextBrand = brandName.concat({
      id: nextId,
      //   nextId 값을 id로 설정
      brand: userInp,
    });
    // nextId를 1증가시킨다.
    setNextId((current) => current + 1);
    setBrandName(nextBrand);
    // input을 비운다.
    setUserInp("");
  };

  const brandList = brandName.map((item) => (
    <li key={item.id}>{item.brand}</li>
  ));
  return <ul>{brandList}</ul>;
  return (
    <>
      <input value={userInp} onChange={onChange} />
      <button onClick={onClick}>브랜드 추가</button>
      <ul>{brandList}</ul>
    </>
  );
};

export default IterationSample;

 

 

 

6.4.2 데이터 제거 기능 구현

 

import { useState } from "react";

const IterationSample = () => {
  // 데이터배열
  const [brandName, setBrandName] = useState([
    { id: 1, brand: "Addidas" },
    { id: 2, brand: "Nike" },
    { id: 3, brand: "New Balance" },
    { id: 4, brand: "Vans" },
  ]);
  //   텍스트 입력할 수 있는 input의 상태
  const [userInp, setUserInp] = useState("");
  // 데이터 배열에서 새로운 항목을 추가할 때 사용할 고유 id를 위한 상태
  //   4개까지 만들었으니 다음 id가 5부터 오게 설정
  const [nextId, setNextId] = useState(5);

  //  input의 value를 업데이트
  const onChange = (event) => {
    setUserInp(event.target.value);
  };
  const onClick = () => {
    //   concat을 사용하여 새로운 항목을 추가한 배열을 만들고, setBrandName을 통해 상태 업데이트
    const nextBrand = brandName.concat({
      id: nextId,
      //   nextId 값을 id로 설정
      brand: userInp,
    });
    // nextId를 1증가시킨다.
    setNextId((current) => current + 1);
    setBrandName(nextBrand);
    // input을 비운다.
    setUserInp("");
  };

  const onRemove = (id) => {
    const removeBrand = brandName.filter((item) => item.id !== id);
    // filter => 배열에서 특정 원소 제외
    setBrandName(removeBrand);
  };

  const brandList = brandName.map((item) => (
    <li key={item.id}>
      {item.brand}
      <button onClick={() => onRemove(item.id)}>삭제</button>
      {/* 인자를 전달할때는 익명함수로 한번 써주고 해야 전달 가능 */}
    </li>
  ));
  return (
    <>
      <input value={userInp} onChange={onChange} />
      <button onClick={onClick}>브랜드 추가</button>
      <ul>{brandList}</ul>
    </>
  );
};

export default IterationSample;

 

 

 

 

새로 알게된 사실

 

 

1.  리액트에서 컴포넌트 배열을 렌더링 할 때 key를 써주어야하는 이유

 

: key가 없을 대는 Virtual DOM을 비교하는 과정에서 리스트를 순차적으로 비교하면서 변화를 감지한다.

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

 

 

2.  index를 key로 사용하면 배열이 변경될 때 효율적으로 리렌더링하지 못한다. (고유한 값이 없을 때만 사용하자)

 

 

3. useState()를 통해서 id를 추가하는 방법을 배웠다.

 

 

4.  내장함수 concat을 사용하여 새로운 항목을 추가한 배열을 만들 수 있다.

 

 

cf) 리액트에서 상태를 업데이트 할 때는 기존 상태를 그대로 두면서 새로운 값을 상태로 설정해야한다. 이를 불변성 유지라고한다.

push 함수는 기존 배열 자체를 변경해주는 반면, concat은 새로운 배열을 만들어준다.

 

 

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

 

const numbers= [1,2,3,4,5,6]

const biggerThanThree =numbers.filter(number => number >3);

//결과 : [4,5,6]

 

6. 불변성을 유지하면서 배열의 특정 항목을 지울 때는 내장함수 filter를 사용한다.

 

const numbers = [1,2,3,4,5,6]

const withoutThree = numbers.filter(number => number !== 3)

// 결과 : [1,2,4,5,6]

 

7. 리액트에서 onClick에 인자를 전달하려고 할때는 익명함수를 써주어야 즉시실행이 되지않게 만들 수 있다.

 

예시 ) <button onClick={() => onRemove(item.id)}>삭제</button>

 

 

8.  상태안에서 배열을 변형할 때는 배열에 직접 접근하여 수정하는 것이 아니라 concat, filter 등의 배열 내장 함수를 사용하여 배열을 

만든 후 이를 새로운 상태로 설정해 주어야 한다

 

 

'📖 리액트 > 리액트를 다루는 기술' 카테고리의 다른 글

8장 Hooks  (2) 2022.01.26
7장 컴포넌트의 라이프사이클 메서드  (0) 2022.01.25
4장 이벤트 헨들링  (0) 2022.01.21
3장 컴포넌트  (0) 2022.01.19
2장 JSX  (0) 2022.01.18