useState 하나로 여러개의 input 관리하기

이로운·2023년 2월 25일
0

react

목록 보기
1/2

인풋 창이 여러개라면 여러분은 어떻게 관리하시겠나요

물론 useState를 여러개 쓰는 방법도 있겠지만..
훅은 성능을 떨어트린다는 글을 본적 있다. ( 사실 랜더링을 계속 하는거니까...?)
useEffect에서 의존성 배열로 리랜더링을 막는 것과 같은 거겠지

유데미 인강으로 리액트 공부를 하는 중 깨달았다

import { useState } from "react";
import "./ExpenseForm.css";

export default function ExpenseForm() {
  const [userInput, setUserInput] = useState({
    enteredTitle: "",
    enteredAmount: "",
    enteredDate: "",
  });

  const titleChangeHandler = (e) => {
    setUserInput({
      // state를 업데이트 하면 여러개의 객체를 한번에 다루는 경우 업데이트 되는 객체를 제외한 나머지를 잃어버리기 때문에 객체를 복사하여 나머지를 잃어버리지 않게 한다
      ...userInput,
      enteredTitle: e.target.vlaue,
    });
  };

  const amountChangeHandler = (e) => {
    setUserInput({
      ...userInput,
      enteredAmount: e.target.vlaue,
    });
  };

  const dataChangeHandler = (e) => {
    setUserInput({
      ...userInput,
      enteredDate: e.target.vlaue,
    });
  };

  return (
    <form>
      <div className="new-expense__controls">
        <div className="new-expense__control">
          <label>Title</label>
          <input type="text" onChange={titleChangeHandler} />
        </div>
        <div className="new-expense__control">
          <label>Amount</label>
          <input
            type="number"
            min="0.01"
            step="0.01"
            onChange={amountChangeHandler}
          />
        </div>
        <div className="new-expense__control">
          <label>Date</label>
          <input
            type="date"
            min="2019-01-01"
            max="2022-12-31"
            onChange={dataChangeHandler}
          />
        </div>
      </div>
      <div className="new-expense__actions">
        <button type="submit">Add Expense</button>
      </div>
    </form>
  );
}

이렇게 객체를 받아서 한번에 세개의 인풋을 관리할 수 있었다
다만 상태 변경으로 인해서 리랜더링이 진행되는 경우 두번째 세번째의 값을 잃어버린다고 한다
생명주기와 관련이 있는듯 해서 이부분은 공부를 더 해봐야할듯 하다

그래서 잃어버리지 않게 스프레드 연산자로 객체를 계속 합성해줘야 한다고 한다

더 좋은 방법

하지만 이것도 완벽히 안전한 방법은 아니라고 한다
중간에 값을 잃어버릴 수도 있기 때문

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

이렇게 콜백 함수로 받는 것이 더 안전하고 최신의 state인 상태로 작업을 할 수 있게 하는 방법이라고 한다

profile
이름 값 하는 개발자가 꿈인 사람

0개의 댓글