혹시나 잘못된 개념 전달이 있다면 댓글 부탁드립니다. 저의 성장의 도움이 됩니다
인풋값을 각각 useState()
로 선언했더니 너무 많은 props 드릴링과 코드가 복잡해졌다.
그래서 state를 하나의 객체 형태로 선언하고, name 속성값을 활용하여 setState도 여러번 사용할 필요가 없이 수정했다.
// 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()
함수는 기본적으로 비동기적으로 작용하지만 동기적으로 작동하는 것처럼 사용할 수도 있다.
값들이 이전값을 기억하고 변해야한다면 아래의 코드를 참조하여 콜백 방식으로 값을 전달해야한다.
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,
};
});
};