본문 바로가기
개발/React

useState 동기화 하는 2가지 방법

by 안뇽! 2023. 2. 28.
반응형

useState

리액트를 조금만 해본 사람이라면 알겠지만 useState의 setState는 비동기로 동작한다.

이번에 회사에서 업무를 하면서 어떤 handler가 setState가 완료된 후에 동작하는것을 보장해야 하는 상황이 있었다.

 

당연히 예상하겠지만, 이 코드는 setState가 끝나기 전에 handleToBottom이 실행된다. 

혹시 이해가 안가면 여기서 실험할 수 있음

<Component ... onClick = {()=>{setState(newState); handleToBottom();}}/>

 

setState가 끝난 후 handleToBottom이 실행되는 것, 즉 setState를 동기화하는 두가지 방법이 있다.

 

1. useEffect

useEffect의 의존성배열을 이용하면 특정 state가 변화할때 동작시키고 싶은 callback함수를 실행시킬 수 있다.

 

// state가 변경되면 handler()가 실행된다.
useEffect(()=>handler(),[state])

너무 기초적인 내용이라 공식문서만 참조

 

하지만 위 방법은 실행과 별개로 유지보수가 어려운 코드를 만들게 되는 것 같다.

(다른 사람이 볼 때, 이 useEffect가 뭐지?? 하는 상황이 올 수 있음)

 

2. setState에 promise걸기

나는 syncSetState.ts라는 handler를 만들었다.

 

// syncSetState.ts
import { Dispatch, SetStateAction } from 'react';

export const syncSetState = <T>(state: T, setState: Dispatch<SetStateAction<T | undefined>>) => {
  return new Promise((resolve) => {
    setState(state);
    resolve('done');
  });
};
// syncSetState에서 setState를 promise로 반환시켜서 동기적으로 실행되게 한다.

return (
  <Component ... onClick = {async ()=>{
    await syncSetState(newState, setState); 
    handleToBottom();}}
   /> )

 

 

3. flushSync

flushSync(()=>callback());

flushSync(()=>setState(newState)); // setState(newState)를 즉시 실행시키고 리렌더링 시킨다.

callback이 비동기 작업일때, 리액트 18의 AutoBatching에서 callback을 제외 시킨다. 즉 즉시실행시킨후에 강제 리렌더링 시킨다.

 

https://wnsdufdl.tistory.com/517

 

flushSync

flushSync : 비동기작업을 동기화 하고 강제 리렌더링 시킨다. 카드를 하나 만들면 스크롤을을 최하단으로 내리는 작업을 하고 있었다. const onAdd = () => { setCards(newCards) scrollToBottom() }; 다음과 같이

wnsdufdl.tistory.com

 

반응형