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
})