useState를 사용하면 state 값이 즉각적으로 업데이트 되는 것이 아니다. useState는 state 업데이트를 예약한다. 따라서 화살표 함수로 이전 상태를 받아서 업데이트 처리를 해야 안전하게 최신 state로 유지할 수 있다.
아래와 같이 화살표 함수를 쓰자!
setState((prevState) => (prevState 업데이트 로직));
const Counter = () => {
const [count, setCount] = useState(0);
const clickHandler = () => {
setCount(count => count + 1);
};
return(
<div>
<h2>{count}</h2>
<button onClick={clickHandler}>
+1
</button>
</div>
);
};
const UserInfo = () => {
const [userInfo, setUserInfo] = useState({
name: '',
age: 0
});
const updateName = () => {
setUserInput(prevInfo => ({
...prevInfo,
name: '이름 변경'
}));
};
const updateAge = () => {
setUserInput(prevInfo => ({
...prevInfo,
age: prevInfo.age + 1
}));
};
return(
<div>
<p>이름: {userInput.name}</p>
<p>나이: {userInput.age}</p>
<button onClick={updateName}>이름 업데이트</button>
<button onClick={updateAge}>나이 업데이트</button>
</div>
);
};
const Form = () => {
const [userInput, setUserInput] = useState({
name: '',
age: '',
birthday: ''
});
// 입력이 바뀌면 실행되는 핸들러
const inputChangeHandler = event => {
const { name, value } = event.target;
setUserInput(prevInput => ({
...prevInput,
[name]: value
}));
};
// submit 버튼을 눌렀을 때 실행되는 핸들러
const submitHandler = event => {
event.preventDefault();
const data = {
name: userInput.name,
age: userInput.age,
birthday: new Date(userInput.birthday)
};
console.log(data); // 확인용
setUserInput({ // 초기화
name: '',
age: '',
birthday: ''
});
};
return (
<form>
<div>
<label>이름</label>
<input
type="text"
name="name"
value={userInput.name}
onChange={inputChangeHandler}
/>
</div>
<div>
<label>나이</label>
<input
type="number"
name="age"
value={userInput.age}
min="0"
step="1"
onChange={inputChangeHandler}
/>
</div>
<div>
<label>생일</label>
<input
type="date"
name="date"
value={userInput.date}
onChange={inputChangeHandler}
/>
</div>
<div>
<button type="submit">제출하기</button>
</div>
</form>
);
};