const [count, setCount] = useState(0)
const click1 = () => {
setCount(count+ 1);
setCount(count+ 1);
console.dir(count);
}
const click2 = () => {
setCount(count=> count+ 1);
setCount(count=> count+ 1);
console.dir(count);
}
setCount에서 값을 변경해 저장하는 방법으로 다음과 같이 두가지 종류가 있다.
click1의 경우 count값을 불러와서 저장한다. 이 때 변경된 값이 바로 저장되는게 아니기 때문에,
setCount(count+ 1); -> (count = 1 : 저장 대기 중 | 현재 값 : count = 0)
setCount(count+ 1); -> (count = 1 : 저장 대기 중 | 현재 값 : count = 0)
console.dir(count); -> count = 0 이므로 0 출력
출력 후, 함수 실행이 끝난 뒤 count값 갱신
이렇게 출력되게 된다.
반대로 안에 화살표 함수를 넣어 count의 값을 변경해주게 되면
setCount(count=> count+ 1); -> (count = 1 : 저장 대기 중 | 현재 값 : count = 0)
setCount(count=> count+ 1); -> (count = 2 : 저장 대기 중 | 현재 값 : count = 1)
console.dir(count);
출력 후, 함수 실행이 끝난 뒤 count값 갱신
이렇게 두 변수 설정 방법에 차이가 나게 된다
그럼 왜 두 방법 모두 함수가 끝난 뒤 변수가 저장되는가 하면
useState가 변수를 변경하는 방식이 비동기로 일어나기 때문이다.
그래서 가급적이면 한 함수 안에서 변경과 값 불러오기가 동시에 사용되는 것을 권장하지 않는다.
여러개의 인자값을 다룰 때 모든 state를 만드는 것보다 객체를 이용해 묶어 사용하는 것이 권장된다.
예를 들어 여러 input의 값을 불러오는 경우,
import React, {useState} from "react";
function InputSample() {
const [inputs, setInputs] = useState({
realname: '',
nickname: ''
});
// 비구조화 할당을 이용해 데이터 추출
const { realname, nickname } = inputs;
const onChange = (e) => {
// 이벤트 타겟에서 name과 value 추출
const {value, name} = e.target;
setInputs({
// 불변성을 지키지 위해 spread 문법 이용
...inputs,
[name] : value
})
};
const onReset = () => {
setInputs({
realname: '',
nickname: '',
})
};
return (
<div>
<input name = "realname" placeholder = "이름" onChange={onChange} value = {realname}/>
<input name = "nickname" placeholder = "닉네임" onChange = {onChange} value = {nickname}/>
<button onClick = {onReset}>초기화</button>
<div>
<b>값: </b>
{realname} ({nickname})
</div>
</div>
);
}
export default InputSample;
setInputs({
// 불변성을 지키지 위해 spread 문법 이용
//...inputs,
[name] : value
})
오브젝트에 inputs값을 얕은 복사 하지 않으면, 기존 값이 저장되지 않는다.
...inputs
이렇게 입력하면
realname : value , nickname : value
값이 데이터로 들어와서
input = {
realname : value ,
nickname : value ,
[name] : value
}
이런식으로 작동하게 되는데
input = {
[name] : value
}
이렇게 기존 값이 새 오브젝트로 덮어지면서 사라져 버린다.
원래는 이런 값이 나와야한다.