<React> 하나의 State에서 여러 값 다루기

·2023년 4월 23일
0

React

목록 보기
2/23

useState로 state를 관리하는 방법은 이때까지 아래와 같은 방법만 알고 있었다.

// 여기
const [title, setTitle] = useState("");
const [amount, setAmount] = useState("");
const [date, setDate] = useState("");

  const titleChangeHandler = (e) => {
    setTitle(e.target.value);
    console.log(" title : ", title);
    console.log(" e : ", e);
  };

  const amountHandler = (e) => {
    setAmount(e.target.value);
    console.log(amount);
  };

  const dateHandler = (e) => {
    setDate(e.target.value);
    console.log(date);
  };

state를 각각 별개로 빼내어 사용하는 방법만 알고있었다면,

오늘 학습한 내용은 하나의 state에 객체를 전달하여 여러 state를 한 번에 관리할 수 있는 것을 알게되었다.

// 이렇게
const [userInput, setUserInput] = useState({
    title : "",
    amount : "",
    date : ""
  })


const titleChangeHandler = (e) => {
    setUserInput({
      ...userInput,
      title: e.target.value,
    });
  };
이전 상태값을 모두 가져온 뒤, title값을 오버라이드하여 상태를 최신화.

이렇게 하나의 useState에 객체로 여러 값을 관리한다면 잊지 말아야 할 것이 있다.

const titleChangeHandler = (e) => {
    setUserInput({
      ...userInput,
      title: e.target.value,
    });
  };

이렇게 스프레드 연산자로 초기값을 가져오지 않고

const titleChangeHandler = (e) => {
    setUserInput({
      title: e.target.value,
    });
  };

이렇게 작성하게 된다면 amount와 date가 state에서 사라지고,
title만 오버라이드 될 것이다.

때문에 반드시 스프레드 연산자를 활용하거나, 하나씩 수기로 작성해주어야 기존의 값을 잃어버리지 않을 수 있다.

하지만 위 처럼 state를 관리하는 방법은 항상 최신의 값을 가져야하는 로직에서는 안전하지 않다.

따라서 훨씬 안전한 아래와 같은 로직 폼을 사용해야 한다.

const [userInput, setUserInput] = useState({
    title: "",
    amount: "",
    date: "",
  });

  const titleChangeHandler = (e) => {
    // 항상 최신의 값을 가져야하는 state에서는 이렇게 콜백 함수로 접근해야한다.
    setUserInput((prevState) => {
      return {
        ...prevState,
        title: e.target.value,
      };
    });

위 함수 Form은 정말로 중요하다.

왜 이렇게 해야할까?

  • 리액트가 상태 업데이트 스케줄을 가지고 있어서 바로 실행하지 않는 것을 명심해야 한다.
  • 콜백 함수로 접근하지 않는다면, 이론적으로 동시에 수많은 상태 업데이트를 계획한다면 오래되었거나 잘못된 스냅샷에 의존할 수 있다.
// 이 방법은 오래되었거나 잘못된 스냅샷에 의존할 수도 있는 로직이다.
const titleChangeHandler = (e) => {
    setUserInput({
      ...userInput,
      title: e.target.value,
    });
  };

// 콜백함수 접근 방법 (해당 로직은 최신 상태 스냅샷을 보장한다.)
const titleChangeHandler = (e) => {
    setUserInput((prevState) => {
      return {
        ...prevState,
        title: e.target.value,
      };
    });
  • 반면 콜백함수 접근 방법을 사용한다면, 리액트는 이 안에 있는 함수에서 prevState 상태 스냅샷이 항상 가장 최신 상태의 스냅샷이라는 것과 항상 계획된 상태 업데이트를 염두에 두고 있다는 것을 보장한다.

정리

  • 콜백함수로 접근하게 되면 항상 최신 상태의 스냅샷에서 작업하도록 하는 더 안전한 방법이다.
    그래서 이전 상태를 기반으로 하는 state를 관리할 때는 콜백 함수 구문을 사용해야 한다.
    (대표적인 예시 : 숫자를 세는 카운트 함수)
// 기초적이며 매우 중요한 로직 ✅
const titleChangeHandler = (e) => {
    setUserInput((prevState) => {
      return {
        ...prevState,
        title: e.target.value,
      };
    });

0개의 댓글