OI7MI

[React] useState 상태 업데이트와 배열에서 특정 항목 삭제하기 본문

프론트엔드/React

[React] useState 상태 업데이트와 배열에서 특정 항목 삭제하기

OI7MI 2026. 1. 9. 03:56
useState 상태 업데이트의 두 가지
1. 단순 값 전달 (Direct Update)

상태를 특정 값으로 완전히 대체하고 싶을 때 사용

setTodo("");

// 단순 값 전달 
// 입력이 끝난 후 input 상태를 빈 문자열로 초기화
  1. 동작 원리: 이전 상태값과 관계없이, 인자로 전달된 새로운 값을 즉시 상태로 반영
  2. 주요 용도: 입력 필드 초기화
    1. 모달창 열기/닫기 (Boolean 값 변경)
    2. 데이터 로딩 상태(Loading/Success/Error) 변경

 

2. 함수형 업데이트 (Functional Update)

이전 상태를 기반으로 새로운 상태를 생성할 때 사용

setTodos((prev) => [todo, ...prev]);

// 함수형 업데이트
// 최신 상태인 prev 배열을 가져와서 새 항목을 결합
  1. 동작 원리: set 함수의 인자로 콜백 함수를 전달. 이때 리액트는 콜백 함수의 첫 번째 인자로 가장 최신의 상태값(State)을 주입
  2. 주요 용도:
    1. 기존 배열에 새로운 항목을 추가할 때 (To-do 리스트 등)
    2. 이전 숫자 값에 특정 연산을 수행할 때 (Counter 등)
  3. 사용 이유: 비동기 업데이트 상황에서도 데이터가 꼬이지 않도록 최신 상태값을 안전하게 참조하기 위해 사용
 
✅ 요약 비교
구분 방식 특징
단순 값 전달 set(value) 이전 상태를 참조하지 않고 값을 변경
함수형 업데이트 set((prev) => newValue) 최신 상태를 인자로 받아 안전하게 업데이트

 


 

 

 

배열에서 특정 항목 삭제하기

 

상태가 배열일 때, 특정 항목만 제외한 새로운 배열을 만들어 업데이트하는 패턴을 사용하는데
filter 메서드를 활용해 깔끔하게 구현할 수 있다
const deleteBtn = (index) => {
  // 최신 상태(prev)를 복사하거나 직접 수정하지 않고 조건에 맞는 항목만 골라서 새로운 배열로 업데이트
  
  setTodos((prev) => prev.filter((_, itemIndex) => index !== itemIndex));
};

동작 원리:

      1. filter : 클릭한 번호(index)와 일치하지 않는 항목들만 모아서 새로운 배열을 생성
      2. _ (언더바): filter의 첫 번째 인자인 '값'은 사용하지 않고, 두 번째 인자인 '인덱스'만 사용하겠다는 자바스크립트 관례

사용 이유:

    • 리액트의 상태는 원본을 직접 수정하면 안 되기 때문에, filter처럼 새로운 배열을 반환하는 메서드를 사용해 안전하게 상태를 교체

 

 

 

 

 


전체 코드
import { useState } from "react";

function App() {
  const [todo, setTodo] = useState(""); // 입력창(input) 텍스트 수정 함수
  const [todos, setTodos] = useState([]); // 할 일 목록 배열(todos) 수정 함수
  const onChange = (e) => setTodo(e.target.value);

  const onSubmit = (e) => {
    e.preventDefault();
    if (todo === "") {
      return;
    }
    setTodos((perv) => [todo, ...perv]);
    setTodo("");
  };

  /** 
   * 삭제 버튼
   * setTodos를 사용하여 전체 목록 업데이트
   * filter를 사용하여 클릭한 index와 일치하지 않는 요소들만 남김
   */
  const deleteBtn = (index) => {
    setTodos((prev) => prev.filter((_, itemIndex) => index !== itemIndex));
  };

  return (
    <div>
      <h1>My To Dos {todos.length}</h1>

      <form onSubmit={onSubmit}>
        <input
          type="text"
          placeholder="Write your to do.."
          onChange={onChange}
          value={todo}
        />
        <button>Add To Do</button>
      </form>
      <hr />
      <ul>
        {todos.map((item, index) => (
          <li key={index}>
            {item} <button onClick={() => deleteBtn(index)}>삭제</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;