React에서 불변성 이해하기: 상태 업데이트 문제 해결
데이터 검색 기능을 구현하기 위해 검색조건 숫자 범위를 state에 저장하고 서버에 전달하려고 했다.
먼저 해당 값을 저장하는 state를 선언하고,
const [wages, setWages] = useState([9860, 9860]);
다음과 같이 focus out 되면 state를 업데이트하는 코드를 작성했다.
<div className='input_wrapper'>
<label>시급</label>
<div className={styles.input_wrapper}>
최소
<input
type='number'
value={wages[0]}
onChange={(e) => handleWageChange(e, 0)}
onBlur={updateWage}
min={9860}
max={1000000}
/>
원 ~ 최대
<input
type='number'
value={wages[1]}
onChange={(e) => handleWageChange(e, 1)}
onBlur={updateWage}
min={9860}
max={1000000}
/>
원
</div>
</div>
const updateWage = () => {
if (wages[0] < 9860) {
alert('최소 시급은 2024년 기준 최저임금 9,860원 이상이어야 합니다.');
setWages([9860, wages[1]])
}
if (wages[0] > wages[1]) {
alert('최대 시급은 최소 시급보다 높아야 합니다.');
setWages([wages[0], wages[0]])
}
setCheckedItems({
...checkedItems,
wage: wages,
});
};
View에서는 정상 작동하는 것으로 보였다.
시급을 0으로 바꾸면 최저시급 미만이라는 오류가 나고, View 상에는 0이 9860으로 변한 것을 볼 수 있었다.
그러나 이때 실제로 서버에 전달되는 값은 0이었다...
동작을 차근히 다시 살펴보았다.
alert가 뜬 다음 조건문을 통해 setWages로 새로운 wages 값을 지정하게 되어 있지만 useState의 상태 변경은 비동기적으로 작용하기 때문에 변동값이 적용되기 전 setCheckedItems가 호출된다.
그리고 value로 wages state를 제공하기 위해서 onChange가 발생할 때마다 state를 변경할 수밖에 없기 때문에, 현재 상태의 state는 입력된 그 값 그대로이다.
위 문제 해결을 위해 다음과 같이 수정했다.
const updateWage = () => {
if (wages[0] < 9860) {
alert('최소 시급은 2024년 기준 최저임금 9,860원 이상이어야 합니다.');
wages[0] = 9860;
}
if (wages[0] > wages[1]) {
alert('최대 시급은 최소 시급보다 높아야 합니다.');
wages[1] = wages[0];
}
setWages(wages);
setCheckedItems({
...checkedItems,
wage: wages,
});
};
좀더 안정적으로 구동하기 위해 다음과 같이 수정했다.
const updateWage = () => {
let newWages = [...wages]; // wages 배열을 복사하여 새로운 배열을 생성
if (newWages[0] < 9860) {
alert('최소 시급은 2024년 기준 최저임금 9,860원 이상이어야 합니다.');
newWages[0] = 9860;
}
if (newWages[0] > newWages[1]) {
alert('최대 시급은 최소 시급보다 높아야 합니다.');
newWages[1] = newWages[0];
}
setWages(newWages); // newWages를 이용하여 한 번에 state를 업데이트
setCheckedItems({
...checkedItems,
wage: newWages,
});
};
이렇게 되면, 원본 배열을 직접 수정하는 것이 아니라 복사본을 수정하기 때문에 예기치 않은 사이드 이펙트를 방지할 수 있다.
첫 번째 수정본에서는 함수 실행 시마다 wages state의 원본 배열을 직접 수정한다. 반면 위 코드에서는 wages 배열의 복사본인 newWages를 만들어 사용하므로, 원본 데이터를 보존하면서 안전하게 작동하는 방식이라고 할 수 있다.
결과적으로 프로그래밍의 '불변성(Immutability)' 원칙을 따르게 되어 함수형 프로그래밍의 핵심 원칙을 준수하게 된다.
'개발 프로젝트 > 스위트케어' 카테고리의 다른 글
스프링 API 서버와 Next.js에서 axiosInstance 사용하기 (0) | 2024.01.22 |
---|---|
한 페이지에서 useModal 커스텀 훅 두 번 호출하기 (0) | 2024.01.17 |
React 상태 업데이트 반응 한 박자씩 늦는 문제 해결하기 (2) | 2024.01.04 |
Next.js에서 동적 라우팅 구현 시 403 에러 해결법 (0) | 2024.01.02 |
Next.js 프로젝트에서 Redirect 시키기 (0) | 2023.12.27 |