MMZ 일지 15. 상태 여러개일때, multiple state 관리

0
post-thumbnail

혹시나 잘못된 개념 전달이 있다면 댓글 부탁드립니다. 저의 성장의 도움이 됩니다

오늘 한 일

  • 등록, 수정페이지 에러 핸들링
  • 북마크 기능 추가: 메인페이지, 레시피 조회 페이지
  • toast 라이브러리 함수화 및 오류 메세지 적용



여러개의 state를 하나의 객체 state로 관리

  • state를 객체로 관리

인풋값을 각각 useState() 로 선언했더니 너무 많은 props 드릴링과 코드가 복잡해졌다.
그래서 state를 하나의 객체 형태로 선언하고, name 속성값을 활용하여 setState도 여러번 사용할 필요가 없이 수정했다.

  • 하나의 핸들러 함수로 여러가지 state 업데이트 가능
    -> input 요소에 name 속성을 추가

// jsx 부분 : styled-componenets를 적용하여 대문자이다.
<SInput
          placeholder="양을 입력해주세요"
          name="amount" //<------------- 객체의 key
          required
          value={inputs.amount}
          onChange={inputHandler}
/>
<SCheckInput
          type="checkbox"
          name="isEssential"  //<------- 객체의 key
          checked={inputs.isEssential}
          onChange={inputHandler}
/>



// 핸들러 함수
const inputHandler = (e: ChangeEvent<HTMLInputElement>) => {
    setInputs((prevState) => {
      return {
        ...prevState,
        [e.target.name]: // <------- jsx에 name 속성을 key 값으로 적용했다.
          e.target.type === "checkbox" ? e.target.checked : e.target.value,
      };
    });
};

함께 변경되는 값에 따라 state를 여러 state 변수로 분할하는 것을 추천합니다.
React 공식문서 : 하나 또는 여러 state 변수를 사용해야 합니까?

위 공식문서에 나온것처럼 상황에 따라 객체로 한꺼번에 관리할지를 판단하면 된다.



setState 함수로 state를 수정하는 2가지 방식

  • 전달인자 콜백으로 사용

setState() 함수는 기본적으로 비동기적으로 작용하지만 동기적으로 작동하는 것처럼 사용할 수도 있다.
값들이 이전값을 기억하고 변해야한다면 아래의 코드를 참조하여 콜백 방식으로 값을 전달해야한다.

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

export default function App() {
  const [count, setCount] = useState(0);
  const [count1, setCount1] = useState(0);

  const handler = () => {
    // 한 함수에서 setState 여러개가 한꺼번에 호출되면 마지막만 적용된다.
    // state는 누적되어 +9가 아닌 마지막에 적용된 +5로 업데이트
    setCount(count + 1);
    setCount(count + 3);
    setCount(count + 5); 
  };
  const handler2 = () => {
    // 콜백방식으로 전달하면 값이 누적되어 동기적으로 사용가능
    // state는 누적되어 +9로 업데이트
    setCount1((count1) => count1 + 1);
    setCount1((count1) => count1 + 3);
    setCount1((count1) => count1 + 5); 
  };

  return (
    <div className="App">
      <button onClick={handler}>값 자체를 전달</button>
      <p>{count}</p> //<------------5
  
      <button onClick={handler2}>콜백으로 전달</button>
      <p>{count1}</p> //<-----------9
    </div>
  );
}

프로젝트 코드에서 위 예시의 handler 함수처럼 갱신할 값자체로 전달했다가, 이럴 경우에 잘못된 상태값에 갱신 될 수도 있다고 한다.
그래서 콜백

// 잘못된 상태에 업데이트 될 수도 있는 방식
const inputHandler = (e: ChangeEvent<HTMLInputElement>) => {
    setInputs({
      ...inputs,
      [e.target.name]:
        e.target.type === "checkbox" ? e.target.checked : e.target.value,
    });
};

그래서 아래의 방식으로 수정하여 기존값에 적용될 수 있도록 수정했다.

// 콜백 방식으로 기존의 값을 받아서 새로운 값을 return하는 함수를 전달
const inputHandler = (e: ChangeEvent<HTMLInputElement>) => {
    setInputs((prevState) => {
      return {
        ...prevState,
        [e.target.name]: 
          e.target.type === "checkbox" ? e.target.checked : e.target.value,
      };
    });
};

0개의 댓글