flushSync
flushSync
๋ React์๊ฒ ์ ๊ณต๋ ์ฝ๋ฐฑ ๋ด๋ถ์ ๋ชจ๋ ์
๋ฐ์ดํธ๋ฅผ ๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ๋๋ก ๊ฐ์ ํฉ๋๋ค. DOM์ด ์ฆ์ ์
๋ฐ์ดํธ๋๋ ๊ฒ์ ๋ณด์ฅํฉ๋๋ค.
flushSync(callback)
๋ ํผ๋ฐ์ค
flushSync(callback)
flushSync
๋ฅผ ํธ์ถํด์ React๊ฐ ๋ณด๋ฅ ์ค์ธ ๋ชจ๋ ์์
์ ๊ฐ์ ๋ก ์ฒ๋ฆฌํ๊ณ DOM์ ๋๊ธฐ์ ์ผ๋ก ์
๋ฐ์ดํธํ ์ ์์ต๋๋ค.
import { flushSync } from 'react-dom';
flushSync(() => {
setSomething(123);
});
๋๋ถ๋ถ์ ๊ฒฝ์ฐ flushSync
์ฌ์ฉ์ ๊ถ์ฅ๋์ง ์์ต๋๋ค. flushSync
๋ ์ตํ์ ์๋จ์ผ๋ก ์ฌ์ฉํ์ธ์.
์๋์์ ๋ ๋ง์ ์์๋ฅผ ํ์ธํ์ธ์.
๋งค๊ฐ๋ณ์
callback
: ํจ์์ ๋๋ค. React๋ ์ฆ์ ์ฝ๋ฐฑ์ ํธ์ถํ๊ณ ์ฝ๋ฐฑ ๋ด์ ๋ชจ๋ ์ ๋ฐ์ดํธ๋ฅผ ๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค. ๋ํ ๋ณด๋ฅ ์ค์ธ ์ ๋ฐ์ดํธ๋ effect ๋๋ effect ๋ด๋ถ์ ์ ๋ฐ์ดํธ๋ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.flushSync
ํธ์ถ๋ก ์ธํด ์ ๋ฐ์ดํธ๊ฐ ์ค๋จ๋๋ฉด fallback์ด ๋ค์ ํ์๋ ์ ์์ต๋๋ค.
๋ฐํ๊ฐ
flushSync
๋ undefined
๋ฅผ ๋ฐํํฉ๋๋ค.
์ฃผ์์ฌํญ
flushSync
๋ฅผ ์ฌ์ฉํ๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฑ๋ฅ์ด ํฌ๊ฒ ์ ํ๋ ์ ์์ต๋๋ค. ๊ฐ๊ธ์ ์ฌ์ฉํ์ง ๋ง์ธ์.flushSync
๋ ๋ณด๋ฅ ์ค์ธ Suspense ๋ฐ์ด๋๋ฆฌ์fallback
state๋ฅผ ํ์ํ๋๋ก ๊ฐ์ ํ ์ ์์ต๋๋ค.flushSync
๋ ๋ณด๋ฅ ์ค์ธ effect๋ฅผ ์คํํ๊ณ ๋ฐํ๋๊ธฐ ์ ์ ํฌํจ๋ ๋ชจ๋ ์ ๋ฐ์ดํธ๋ฅผ ๋๊ธฐ์ ์ผ๋ก ์ ์ฉํ ์ ์์ต๋๋ค.flushSync
๋ ์ฝ๋ฐฑ ๋ด๋ถ์ ์ ๋ฐ์ดํธ๋ฅผ ์ฒ๋ฆฌํ ๋ ํ์ํ ๊ฒฝ์ฐ ์ฝ๋ฐฑ ์ธ๋ถ์ ์ ๋ฐ์ดํธ๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ํด๋ฆญ์ผ๋ก ์ธํ ๋ณด๋ฅ ์ค์ธ ์ ๋ฐ์ดํธ๊ฐ ์๋ ๊ฒฝ์ฐ React๋ ์ฝ๋ฐฑ ๋ด๋ถ์ ์ ๋ฐ์ดํธ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ ์ ํด๋น ์ ๋ฐ์ดํธ๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
์ฌ์ฉ๋ฒ
์จ๋ํํฐ ํตํฉ์ ์ํ ์ ๋ฐ์ดํธ flushing
๋ธ๋ผ์ฐ์ API ๋๋ UI ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ฐ์ ์จ๋ํํฐ ์ฝ๋๋ฅผ ํตํฉํ ๋ React๊ฐ ์
๋ฐ์ดํธ๋ฅผ ์ฒ๋ฆฌํ๋๋ก ๊ฐ์ ํ ํ์๊ฐ ์์ ์ ์์ต๋๋ค. flushSync
๋ฅผ ์ฌ์ฉํด์ React๊ฐ ์ฝ๋ฐฑ ๋ด๋ถ์ ๋ชจ๋ state updates๋ฅผ ๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ๋๋ก ํ ์ ์์ต๋๋ค.
flushSync(() => {
setSomething(123);
});
// By this line, the DOM is updated.
์ด๋ ๊ฒ ํจ์ผ๋ก์จ React๊ฐ DOM์ ์ด๋ฏธ ์ ๋ฐ์ดํธํ ํ์ ๋ค์ ์ค์ ์ฝ๋๋ฅผ ์คํํ๋ ๊ฒ์ ๋ณด์ฅํฉ๋๋ค.
flushSync
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ผ๋ฐ์ ์ด์ง ์๊ณ ์์ฃผ ์ฌ์ฉํ๋ฉด ์ ํ๋ฆฌ์ผ์ด์
์ ์ฑ๋ฅ์ด ํฌ๊ฒ ์ ํ๋ ์ ์์ต๋๋ค. ์ ํ๋ฆฌ์ผ์ด์
์ด React API๋ง ์ฌ์ฉํ๊ณ ์จ๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํตํฉํ์ง ์๋๋ค๋ฉด flushSync
๋ ํ์ํ์ง ์์ต๋๋ค.
๊ทธ๋ฌ๋ ๋ธ๋ผ์ฐ์ API์ ๊ฐ์ ์จ๋ํํฐ ์ฝ๋์ ํตํฉํ ๋ ์ ์ฉํ ์ ์์ต๋๋ค.
์ผ๋ถ ๋ธ๋ผ์ฐ์ API๋ ์ฝ๋ฐฑ ๋ด๋ถ์ ๊ฒฐ๊ณผ๊ฐ DOM์์ ๋๊ธฐ์ ์ผ๋ก ์ฌ์ฉ๋ ๊ฒ์ผ๋ก ์์ํ๋ฏ๋ก ์ฝ๋ฐฑ์ด ์๋ฃ๋ ๋๊น์ง ๋ ๋๋ง๋ DOM์ ์ฌ์ฉํด์ ๋ธ๋ผ์ฐ์ ๊ฐ ์์ ํ ์ ์์ต๋๋ค. ๋๋ถ๋ถ์ ๊ฒฝ์ฐ React๊ฐ ์ด๋ฅผ ์๋์ผ๋ก ์ฒ๋ฆฌํ์ง๋ง, ๋์ ๋ฐ๋ผ ๊ฐ์ ๋ก ๋๊ธฐ์ ์ ๋ฐ์ดํธ๋ฅผ ํด์ผ ํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด onbeforeprint
๋ธ๋ผ์ฐ์ API๋ฅผ ์ฌ์ฉํ๋ฉด ํ๋ฆฐํธ ๋ค์ด์ผ๋ก๊ทธ๊ฐ ์ด๋ฆฌ๊ธฐ ์ง์ ์ ํ์ด์ง๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ๋ฌธ์๋ฅผ ๋ ์ ํ์ํ๊ธฐ ์ํด ์ฌ์ฉ์๊ฐ ์ ์ํ ํ๋ฆฐํธ ์คํ์ผ์ ์ ์ฉํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค. ์๋ ์์์์๋ onbeforeprint
์ฝ๋ฐฑ ๋ด์์ flushSync
๋ฅผ ์ฌ์ฉํ์ฌ React state๋ฅผ DOM์ผ๋ก ์ฆ์ โflushโํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ํ๋ฆฐํธ ๋ค์ด์ผ๋ก๊ทธ๊ฐ ์ด๋ฆด ๋๊น์ง 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๊ฐ ์
๋ฐ์ดํธ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก batchํ๊ณ ํ๋ฆฐํธ ๋ค์ด์ผ๋ก๊ทธ๋ฅผ state๊ฐ ์
๋ฐ์ดํธ๋๊ธฐ ์ ์ ํ์ํ๊ธฐ ๋๋ฌธ์
๋๋ค.