OLD/React
[React] React에서 이전 상태를 기반으로 한 상태 업데이트를 올바르게 하는 방법
joseph0926
2024. 6. 4. 18:48
React에서 상태를 다루다 보면 이전 상태에 기반해서 상태를 업데이트를 해야하는 경우가 많습니다
예를들어 토글 버튼이 있을 수 있습니다.
버튼을 클릭할때마다 드롭다운이 나타나고 사라지는 예시가 될 수 있습니다.
그럴때 아래와 같이 코드를 작성할 수 있습니다.
const [isOpen, setIsOpen] = useState(false)
const dropdownHandler = () => {
setIsOpen(!isOpen)
}
하지만 위와 같이 작성한 코드는 React 팀에서 권장하는 코드가 아닙니다.
React 공식문서 Updating state based on the previous state
useState – React
The library for web and native user interfaces
react.dev
위의 문서에 자세히 나와있지만, 결론적으로 말하면 React에서 상태를 업데이트하는 매커니즘 때문입니다.
React는 상태를 업데이트할 때 일종의 스케쥴링 매커니즘이 존재합니다.
즉, 상태 변경을 즉각적으로 진행하는 것이 아니라 상태 변경을 스케쥴링하고 수행합니다 (물론 이 과정은 일반적으로 x ms 단위입니다)
코드로 살펴보면 다음과 같습니다
const updateHandler = () => {
// 기존 상태가 false라 가정
setIsOpen(!isOpen) // true로 예측됨
setIsOpen(!isOpen) // false로 예측됨
// 결과적으로 state가 변화가 없을 것으로 예측됨
}
// 하지만 결과는 false로 변경됨
// 위의 코드를 서술하면 아래와 같음
setIsOpen(!isOpen) => state를 true로 바꾸라는 스케쥴이 생성됨
setIsOpen(!isOpen) => state를 true로 바꾸라는 스케쥴이 생성됨 (왜냐하면 아직 위에 스케쥴이 실제로 실행되지 않음)
반면 올바르게 업데이트하는 방법은 아래와 같습니다.
const updateHandler = () => {
// 기존 상태가 false라 가정
setIsOpen(prevState => !prevState) // true로 예측됨
setIsOpen(prevState => !prevState) // false로 예측됨
// 결과적으로 state가 변화가 없을 것으로 예측됨
}
// 실제로 state가 원상태
객체나 배열도 같은 방식으로 업데이트를 진행하지만 하나의 단계가 더 추가됩니다.
=> 원본에 직접 값을 업데이트하는게 아닌, 복사 후 복사본에 값을 업데이트 하는 방식입니다
const exArray = [
[null, null, null],
[null, null, null],
[null, null, null],
]
const [newArray, setNewArray] = useState(exArray)
// 잘못된 업데이트 방식
setNewArray(prevArray => {
prevArray[0][0] = "1"
return prevArray
})
// 올바른 업데이트 방식
setNewArray(prevArray => {
const updatedArray = [...prevArray.map(innerArray => [...innerArray])]
updatedArray[0][0] = "1"
return updatedArray
})