-
30. Final Project [trouble shooting-3] - useState비동기문제 함수형 업데이트로 해결! chat GPT야 고마워Java Script & Type Script/Trouble Shooting 2023. 2. 23. 12:14728x90
발생한 문제
Server Sent Event를 이용해 알림받는 페이지를 구현하는 도중, 알림이 도착해서 첫 알림은 화면에 잘 렌더링이 되나, 두번째, 세번째 알림이 올 때 알림이 축적되는 것이 아닌, 첫번째 알림을 새로운 알림이 대체해버리는 문제점을 발견했다.
이용하고있던 해당 코드는 아래와 같다. notifications배열에 새 알림을 첫번째로 가져오고 기존 알림을 spread연산자로 불변성을 유지하며 새 배열을 만들 의도였다.
setNotifications([newNotification, ...notifications])
이 문제점은 useState hook이 비동기적으로 동작하기 때문에 setNotifications 함수가 실행될 때 notifications 배열의 최신 값을 반영하지 않은 것이 원인이었다.
비동기적으로 작동한다는 useState훅의 특성때문에 setState를 사용하여 상태를 업데이트할 경우, 업데이트 된 상태는 즉시 반영되지 않는다. 리렌더링이 된 후에야 비로소 state 업데이트가 반영된다. ( state 변경 - 리렌더링 - state 반영 )
리액트의 state를 업데이트하는 데있어서, 비동기적으로 작동하는 속성은 여러개의 state를 다룰 때 퍼포먼스측면에서 유리하다. 동기적으로 작동했다면 state1 업데이트 - state2 업데이트... 이런식으로 하나씩 업데이트가 될테니까.
여러 state를 동시에 업데이트하는 경우, 리액트는 state를 batching하여 업데이트를 진행한다.
(batching = 전달된 오브젝트들을 하나로 합치는 작업)
리액트 batching 예제
const [value, setValue] = useState(0); setValue(value + 1); setValue(value + 1); setValue(value + 1); // Expected value: 3 // Result value: 1
이러한 특성때문에 업데이트된 state를 즉시 반영해야 할 때, 우리는 useEffect()를 사용한다.
setState 를 동기적으로 사용하는 방법은 함수형 업데이트!
이러한 비동기적인 방법을 해결하기 위해서 우리는 함수형 업데이트(functional update)를 사용할 수 있다.
즉 setState에 값을 그대로 전달하는 것이 아니라 함수를 전달하는 것이다
const [value, setValue] = useState(0); setValue(prev => prev + 1); setValue(prev => prev + 1); setValue(prev => prev + 1); // Expected value: 3 // Result value: 3
함수형 업데이트는 useCallback과 함께 props로 전될된 함수를 최적화할 때도 유용하게 사용될 수 있다. 예를 들어 handleClick함수가 자식 컴포넌트에게 props를 통해서 전달 될 경우, 우리는 useCallback을 사용해서 함수를 감싼다.
const handleToggle = useCallback((): void => setIsClicked(!isClicked), [isClicked]);
하지만 이 경우, useCallback과 함께 사용을 하더라도 isClicked에 대한 의존성 배열을 가지게 된다. 이 때 아예 의존성을 없게 만들고 싶다면 함수형 업데이트를 사용할 수 있다.
const handleToggle = useCallback((): void => setIsClicked(prev => !prev), []);
챗 GPT가 함수형업데이트를 추천해줬다..
넌 짱이야
728x90'Java Script & Type Script > Trouble Shooting' 카테고리의 다른 글
[JS] this 바인딩에대한 고찰... (항해 수료 후 근황, 스파르타 취업준비반) (0) 2023.04.03 38. 3월 16일 (0) 2023.03.16 34. react-datepicker 야무지게 잘 쓰는 법. Feat.datepicker 시차해결. datepicker한국시간표현 (0) 2023.03.04 [JS, TS]TypeError: cannot read properties of undefined (reading 'length') (해결)(+3월 17일 수정) (2) 2023.02.18 27. Final project [Trouble Shooting -1]리액트 무한렌더링-불필요한 렌더링을 막는 리액트 훅 useCallback, useMemo (해결중) (0) 2023.02.16