flushSync
⚠️ flushSync 사용은 드물며, 앱의 성능을 저하시킬 수 있습니다.
flushSync
는 제공된 콜백 내부의 React 업데이트를 동기적으로 즉시 DOM에 반영하도록 강제합니다.
flushSync(callback)
- 레퍼런스
- flushSync(callback)
- 사용법
- 서드파티(3rd-party) 연동 시 업데이트 즉시 반영하기
레퍼런스
flushSync(callback)
flushSync
를 호출하면 React가 대기 중인 작업을 모두 즉시 처리하고, DOM을 동기적으로 업데이트합니다.
import { flushSync } from 'react-dom';
flushSync(() => {
setSomething(123);
});
대부분의 경우 flushSync는 필요하지 않습니다. 정말 마지막 수단으로만 사용하세요.
파라미터
callback
: 함수. React가 이 콜백을 즉시 실행하며, 콜백 내의 모든 업데이트를 동기적으로 반영합니다. 대기 중인 업데이트, Effect, Effect 내부의 업데이트도 함께 처리될 수 있습니다. 만약 이 flushSync 호출로 인해 업데이트가 일시 중단(suspend)되면, fallback UI가 다시 표시될 수 있습니다.
반환값
flushSync
는 undefined
를 반환합니다.
주의사항
- flushSync는 성능에 큰 영향을 줄 수 있으니 꼭 필요한 경우에만 사용하세요.
- flushSync는 대기 중인 Suspense 경계의 fallback UI를 강제로 표시할 수 있습니다.
- flushSync는 대기 중인 Effect를 실행하고, 그 안의 업데이트도 동기적으로 적용할 수 있습니다.
- flushSync는 콜백 외부의 업데이트도, 콜백 내부의 업데이트를 동기적으로 처리하기 위해 필요하다면 함께 처리할 수 있습니다. 예를 들어, 클릭 이벤트에서 대기 중인 업데이트가 있다면, flushSync는 콜백 내부 업데이트를 처리하기 전에 해당 업데이트도 처리할 수 있습니다.
사용법
서드파티 연동 시 업데이트 즉시 반영하기
브라우저 API나 UI 라이브러리 등 서드파티 코드와 연동할 때, React의 업데이트를 강제로 즉시 반영해야 할 때가 있습니다. 이럴 때 flushSync를 사용하세요:
flushSync(() => {
setSomething(123);
});
// 이 시점에서 DOM이 이미 업데이트됨
이렇게 하면 다음 코드가 실행될 때 React가 이미 DOM을 업데이트한 상태임이 보장됩니다.
flushSync 사용은 매우 드물며, 자주 사용하면 앱의 성능이 크게 저하될 수 있습니다.
React API만 사용하는 앱, 서드파티 라이브러리와 연동하지 않는 앱에서는 flushSync가 필요하지 않습니다.
하지만 브라우저 API 등 일부 서드파티 코드는 콜백 내에서 결과가 DOM에 동기적으로 반영되길 기대할 수 있습니다. 대부분의 경우 React가 자동으로 처리하지만, 정말 필요한 경우 flushSync로 동기 업데이트를 강제할 수 있습니다.
예를 들어, 브라우저의 onbeforeprint
API는 프린트 다이얼로그가 열리기 직전에 페이지를 변경할 수 있게 해줍니다. 아래 예시처럼, onbeforeprint 콜백에서 flushSync를 사용하면 프린트 다이얼로그가 열릴 때까지 isPrinting
이 "yes"로 표시됩니다:
import { useState, useEffect } from 'react';
import { flushSync } from 'react-dom';
export default function PrintApp() {
const [isPrinting, setIsPrinting] = useState(false);
useEffect(() => {
function handleBeforePrint() {
flushSync(() => {
setIsPrinting(true);
})
}
function handleAfterPrint() {
setIsPrinting(false);
}
window.addEventListener('beforeprint', handleBeforePrint);
window.addEventListener('afterprint', handleAfterPrint);
return () => {
window.removeEventListener('beforeprint', handleBeforePrint);
window.removeEventListener('afterprint', handleAfterPrint);
}
}, []);
return (
<>
<h1>isPrinting: {isPrinting ? 'yes' : 'no'}</h1>
<button onClick={() => window.print()}>
Print
</button>
</>
);
}
flushSync를 사용하지 않으면, 프린트 다이얼로그가 열릴 때 isPrinting
이 "no"로 표시될 수 있습니다. 이는 React가 업데이트를 비동기로 처리하기 때문입니다.