React에서 배열 데이터 삭제하기

kyeongboo·2023년 5월 10일

React에서 button components를 추가하여 해당 button을 클릭하면 데이터가 하나씩 삭제되게 하는 코드는?

  • App.js
import { useState } from "react";

function App() {
  const [datas, setDatas] = useState([
    {
      title: "개발자 무릎 담요",
      price: 17500,
      id: 101,
    },
    {
      title: "Hack Your Life 개발자 노트북 파우치",
      price: 29000,
      id: 102,
    },
    {
      title: "우당탕탕 라이켓의 실험실 스티커북",
      price: 29000,
      id: 103,
    },
    {
      title: "버그를 Java라 버그잡는 개리씨 키링",
      price: 29000,
      id: 104,
    },
  ]);

  function handleClick(id) {
    setDatas((prevDatas) => {
      return prevDatas.filter((item) => {
        console.log(item);
        return id !== item.id;
      });
    });
  }

  return (
    <>
      {datas.map((item, idx) => (
        <li key={item.id} style={{ listStyle: "none" }}>
          <h2>
            {idx + 1}
            {item.title}
          </h2>
          <span>{`${item.price}`}</span>
          <button
            onClick={() => {
              handleClick(item.id);
            }}
          >
            삭제
          </button>
        </li>
      ))}
    </>
  );
}

export default App;

가장 먼저 button components를 추가하기 전에 사용자가 삭제버튼을 누를 때 바뀐 컴포넌트를 보여줄 수 있도록 컴포넌트에서 바뀐 값을 관리하는 useState 함수를 추가합니다. useState의 초기 값으로 객체 내용을 추가합니다.

     <button
            onClick={() => {
              handleClick(item.id);
            }}
          >
            삭제
          </button>

그 다음 return()안에 위와 같은 button 컴포넌트를 추가해주고 onClick이라는 이벤트 처리를 진행합니다.

  • button components가 추가된 모습
  function handleClick(id) {
    setDatas((prevDatas) => {
      return prevDatas.filter((item) => {
        console.log(item);
        return id !== item.id;
      });
    });
  }

다음 handleClick() 함수에서 삭제 대상의 객체 id 값을 매개변수로 받아 해당 id 값을 제외한 나머지의 데이터를 filter()함수를 이용해서 return 하도록 합니다.

  • button 클릭시 삭제 된 모습

return 된 값을 최종적으로 setDatas함수가 처리하여 데이터가 재 렌더링 되면서 데이터가 삭제되는 것을 확인할 수 있습니다.

  function handleClick(id) {
    setDatas((prevDatas) => {
      return prevDatas.filter((item) => {
        console.log(item);
        return id !== item.id;
      });
    });
  }

그런데 여기서 위 코드와 같이 함수형 업데이트로 처리한 이유는 무엇일까?

import { useState } from "react";

export default function Counter() {
  const [number, setNumber] = useState(0);

  function increment() {
    setNumber(number + 1)
    setNumber(number + 1)
    setNumber(number + 1)
  }

  return (
    <div>
      <h1>Counter : {number}</h1>
      <button onClick={increment}>+1</button>
    </div>
  );
}

위 코드에서 setNumber(number + 1)를 3번 호출 했기 때문에 1이 아닌 3씩 증가할거라 예상하겠지만 여전히 1씩 증가합니다. 이유는 React는 동일한 state를 연속적으로 처리하는 경우에 여러 개의 상태 값 변경 요청을 일괄처리하기 때문입니다. 즉 전달된 setState을 합친 후에 최종적으로 한번의 setState를 하게 된다는 점입니다. 이렇듯 리액트가 상태 값을 일괄처리하는 이유는 리렌더링이 발생하는 setState가 일어날 때마다 리렌더링을 하게 되면 너무 많은 렌더링이 발생하여 성능 문제가 일어날 수 있기 때문입니다.

  function handleClick(id) {
    setDatas((prevDatas) => {
      return prevDatas.filter((item) => {
        console.log(item);
        return id !== item.id;
      });
    });
  }

그래서 이렇게 비동기로 동작하는 함수를 동기적으로 처리하기 위해서 즉 setState함수가 비동기로 수행할 때 값을 전달하지 말고 업데이트된 최신의 state와 함께 함수를 전달하기 위해서 함수형 업데이트를 사용합니다.

함수형 업데이트 방법으로 prev를 사용하면 되는데 위 코드 처럼 pre로도 사용 가능합니다. prev를 사용해 함수의 인자로 전달되는 state 값을 이전 state 값으로 보장하여 안정적으로 이전 값과 이후 값을 비교하여 처리할 수 있습니다.

profile
적극성과 커뮤니케이션 능력이 겸비된 개발자로 성장하자!

0개의 댓글