useLayoutEffect
useLayoutEffect๋ ๋ธ๋ผ์ฐ์ ๊ฐ ํ๋ฉด์ ๋ค์ ๊ทธ๋ฆฌ๊ธฐ ์ ์ ์คํ๋๋ useEffect์
๋๋ค.
useLayoutEffect(setup, dependencies?)๋ ํผ๋ฐ์ค
useLayoutEffect(setup, dependencies?)
useLayoutEffect๋ฅผ ํธ์ถํ์ฌ ๋ธ๋ผ์ฐ์ ๊ฐ ํ๋ฉด์ ๋ค์ ๊ทธ๋ฆฌ๊ธฐ ์ ์ ๋ ์ด์์์ ๊ณ์ฐํฉ๋๋ค.
import { useState, useRef, useLayoutEffect } from 'react';
function Tooltip() {
const ref = useRef(null);
const [tooltipHeight, setTooltipHeight] = useState(0);
useLayoutEffect(() => {
const { height } = ref.current.getBoundingClientRect();
setTooltipHeight(height);
}, []);
// ...์๋์์ ๋ ๋ง์ ์์๋ฅผ ํ์ธํ์ธ์.
๋งค๊ฐ๋ณ์
-
setup: The function with your Effectโs logic. Your setup function may also optionally return a cleanup function. Before your component is added to the DOM, React will run your setup function. After every re-render with changed dependencies, React will first run the cleanup function (if you provided it) with the old values, and then run your setup function with the new values. Before your component is removed from the DOM, React will run your cleanup function. -
optional
dependencies: The list of all reactive values referenced inside of thesetupcode. Reactive values include props, state, and all the variables and functions declared directly inside your component body. If your linter is configured for React, it will verify that every reactive value is correctly specified as a dependency. The list of dependencies must have a constant number of items and be written inline like[dep1, dep2, dep3]. React will compare each dependency with its previous value using theObject.iscomparison. If you omit this argument, your Effect will re-run after every re-render of the component. -
์ ํ์ฌํญ
dependencies:setup์ฝ๋ ๋ด์์ ์ฐธ์กฐ๋ ๋ชจ๋ ๋ฐ์ํ ๊ฐ์ ๋ชฉ๋ก์ ๋๋ค. ๋ฐ์ํ ๊ฐ์๋ props, state, ๊ทธ๋ฆฌ๊ณ ์ปดํฌ๋ํธ ๋ณธ๋ฌธ์ ์ง์ ์ ์ธ๋ ๋ชจ๋ ๋ณ์์ ํจ์๊ฐ ํฌํจ๋ฉ๋๋ค. linter๊ฐ React์ฉ์ผ๋ก ์ค์ ๋ ๊ฒฝ์ฐ, ๋ชจ๋ ๋ฐ์ํ ๊ฐ์ด ์์กด์ฑ์ผ๋ก ์ฌ๋ฐ๋ฅด๊ฒ ์ง์ ๋์๋์ง ํ์ธํฉ๋๋ค. ์์กด์ฑ ๋ชฉ๋ก์๋ ์ผ์ ํ ์์ ํญ๋ชฉ์ด ์์ด์ผ ํ๋ฉฐ[dep1, dep2, dep3]์ ๊ฐ์ด ์์ฑํด์ผ ํฉ๋๋ค. React๋Object.is๋น๊ต ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ฌ ๊ฐ ์์กด์ฑ์ ์ด์ ๊ฐ๊ณผ ๋น๊ตํฉ๋๋ค. ์์กด์ฑ์ ์ ํ ์ง์ ํ์ง ์์ผ๋ฉด ์ปดํฌ๋ํธ๋ฅผ ๋ค์ ๋ ๋๋งํ ๋๋ง๋ค Effect๊ฐ ๋ค์ ์คํ๋ฉ๋๋ค.
๋ฐํ๊ฐ
useLayoutEffect๋ undefined๋ฅผ ๋ฐํํฉ๋๋ค.
์ฃผ์ ์ฌํญ
-
useLayoutEffect๋ Hook์ด๋ฏ๋ก, ์ปดํฌ๋ํธ์ ์ต์์ ๋ ๋ฒจ ๋๋ ์ปค์คํ Hook์์๋ง ํธ์ถํ ์ ์์ต๋๋ค. ๋ฐ๋ณต๋ฌธ์ด๋ ์กฐ๊ฑด๋ฌธ ๋ด์์ ํธ์ถํ ์ ์์ต๋๋ค. ์ด ์์ ์ด ํ์ํ๋ค๋ฉด ์๋ก์ด ์ปดํฌ๋ํธ๋ก ๋ถ๋ฆฌํด์ Effect๋ฅผ ์ ์ปดํฌ๋ํธ๋ก ์ฎ๊ธฐ์ธ์. -
Strict Mode๊ฐ ์ผ์ ธ ์์ผ๋ฉด, React๋ ์ค์ ์ฒซ ๋ฒ์งธ setup ํจ์๊ฐ ์คํ๋๊ธฐ ์ด์ ์ ๊ฐ๋ฐ ๋ชจ๋์๋ง ํ์ ํ์ฌ ํ ๋ฒ์ ์ถ๊ฐ์ ์ธ setup + cleanup ์ฌ์ดํด์ ์คํํฉ๋๋ค. ์ด๋ cleanup ๋ก์ง์ด setup ๋ก์ง์ ์๋ฒฝํ โ๋ฐ์โํ๊ณ , setup ๋ก์ง์ด ์ํํ๋ ์์ ์ ์ค๋จํ๊ฑฐ๋ ๋๋๋ฆฌ๋ ์ง๋ฅผ ํ์ธํ๋ ์คํธ๋ ์ค ํ ์คํธ์ ๋๋ค. ์ด๋ก ์ธํด ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ฉด cleanup ํจ์๋ฅผ ๊ตฌํํ์ธ์.
-
์์กด์ฑ ์ค์ ์ปดํฌ๋ํธ ๋ด๋ถ์์ ์ ์๋ ๊ฐ์ฒด๋ ํจ์๊ฐ ์๋ ๊ฒฝ์ฐ, Effect ๊ฐ ํ์ ์ด์์ผ๋ก ๋ค์ ์คํ๋ ์ํ์ด ์์ต๋๋ค. ์ด๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด ๋ถํ์ํ ๊ฐ์ฒด ์์กด์ฑ์ด๋ ํจ์ ์์กด์ฑ์ ์ ๊ฑฐํ์ธ์. State ์ ๋ฐ์ดํธ๋ ๋น ๋ฐ์ํ ๋ก์ง์ effect ๋ฐ์ผ๋ก ๋นผ๋ผ ์ ๋ ์์ต๋๋ค.
-
Effect๋ ํด๋ผ์ด์ธํธ ํ๊ฒฝ์์๋ง ๋์ํฉ๋๋ค. ์๋ฒ ๋ ๋๋ง ์ค์๋ ์คํ๋์ง ์์ต๋๋ค.
-
useLayoutEffect๋ด๋ถ์ ์ฝ๋์ ์ด๋ก ์ธํ ๋ชจ๋ state ์ ๋ฐ์ดํธ๋ ๋ธ๋ผ์ฐ์ ๊ฐ ํ๋ฉด์ ๋ค์ ๊ทธ๋ฆฌ๋ ๊ฒ์ ๋ง์ต๋๋ค. ๊ณผ๋ํ๊ฒ ์ฌ์ฉํ๋ฉด ์ฑ์ด ๋๋ ค์ง๋๋ค. ๊ฐ๋ฅํ๋ฉดuseEffect๋ฅผ ์ฌ์ฉํ์ธ์. -
useLayoutEffect๋ด๋ถ์์ state ์ ๋ฐ์ดํธ๋ฅผ ์คํํ๋ฉด React๋useEffect๋ฅผ ํฌํจํ ๋๋จธ์ง ๋ชจ๋ Effect๋ฅผ ์ฆ์ ์คํํฉ๋๋ค.
์ฌ์ฉ๋ฒ
๋ธ๋ผ์ฐ์ ๊ฐ ํ๋ฉด์ ๋ค์ ๊ทธ๋ฆฌ๊ธฐ ์ ์ ๋ ์ด์์ ๊ณ์ฐํ๊ธฐ
๋๋ถ๋ถ์ ์ปดํฌ๋ํธ๋ ๋ ๋๋ง์ ์ํด ํด๋น ์ปดํฌ๋ํธ์ ํ๋ฉด์ ์์น์ ํฌ๊ธฐ๋ฅผ ์ ํ์๊ฐ ์์ต๋๋ค. ์ปดํฌ๋ํธ๊ฐ JSX๋ฅผ ๋ฐํํ๋ฉด ๋ธ๋ผ์ฐ์ ๊ฐ ์ปดํฌ๋ํธ์ ๋ ์ด์์(์์น์ ํฌ๊ธฐ)๋ฅผ ๊ณ์ฐํ๊ณ ํ๋ฉด์ ๋ค์ ๊ทธ๋ฆฝ๋๋ค.
๊ฐ๋์ ์ด๊ฒ๋ง์ผ๋ก๋ ๋ถ์กฑํ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ๋ง์ฐ์ค ์ปค์๋ฅผ ์ฌ๋ฆฌ๋ฉด ํดํ์ด ์์ ์์ ๋ํ๋๋ ๊ฒฝ์ฐ๋ฅผ ์๊ฐํด ๋ณด์ธ์. ์ถฉ๋ถํ ๊ณต๊ฐ์ด ์๋ค๋ฉด ํดํ์ ์์ ์์ ๋ํ๋๊ฒ ์ง๋ง, ๊ณต๊ฐ์ด ๋ถ์กฑํ๋ค๋ฉด ์๋์ ๋ํ๋์ผ ํฉ๋๋ค. ๊ฒฐ๊ตญ ํดํ์ ์ฌ๋ฐ๋ฅธ ์์น์ ๋ ๋๋งํ๋ ค๋ฉด ํดํ์ ๋์ด๋ฅผ ์์์ผ ํฉ๋๋ค. (์์ชฝ ๊ณต๊ฐ์ ๋ค์ด๊ฐ๋์ง ํ๋จ ํด์ผ ํจ)
์ด๋ฅผ ์ํด ๋ ๋ฒ์ ๋ ๋๋ง์ ๊ฑฐ์ณ์ผ ํฉ๋๋ค.
- ํดํ์ (์๋ชป๋ ์์น๋ผ๋) ์๋ฌด ์์น์ ๋ ๋๋งํฉ๋๋ค
- ํดํ์ ๋์ด๋ฅผ ๊ณ์ฐํด์ ํดํ์ ๋ฐฐ์นํ ์์น๋ฅผ ๊ฒฐ์ ํฉ๋๋ค.
- ์ฌ๋ฐ๋ฅธ ์์น์ ํดํ์ ๋ค์ ๋ ๋๋งํฉ๋๋ค.
์ด ์์
์ ๋ธ๋ผ์ฐ์ ๊ฐ ํ๋ฉด์ ๋ค์ ๊ทธ๋ฆฌ๊ธฐ ์ ์ ๋ชจ๋ ์ด๋ฃจ์ด์ ธ์ผ ํฉ๋๋ค. ํดํ์ด ์์ง์ด๋ ๊ฑธ ์ฌ์ฉ์์๊ฒ ๋ณด์ด๊ณ ์ถ์ง ์์ผ๋๊น์. useLayoutEffect๋ฅผ ํธ์ถํด์ ๋ธ๋ผ์ฐ์ ๊ฐ ํ๋ฉด์ ๋ค์ ๊ทธ๋ฆฌ๊ธฐ ์ ์ ๋ ์ด์์์ ๊ณ์ฐํ์ธ์.
function Tooltip() {
const ref = useRef(null);
const [tooltipHeight, setTooltipHeight] = useState(0); // ์์ง ์ค์ ๋์ด๋ฅผ ๋ชจ๋ฆ
๋๋ค.
useLayoutEffect(() => {
const { height } = ref.current.getBoundingClientRect();
setTooltipHeight(height); // ์ค์ ๋์ด๋ฅผ ์์์ผ๋ ๋ค์ ๋ ๋๋งํฉ๋๋ค.
}, []);
// ...์๋์ ์ฌ ๋ ๋๋ง ๋ก์ง์์ tooltipHeight๋ฅผ ์ฌ์ฉํ์ธ์...
}์๋ ๋ฐฉ์์ ๋จ๊ณ๋ณ๋ก ์์๋ด ์๋ค.
Tooltip์ ์ด๊ธฐํ๋ ๊ฐ์ธtooltipHeight = 0์ผ๋ก ๋ ๋๋ง ๋ฉ๋๋ค (๋ฐ๋ผ์ ํดํ์ ์์น๋ ์๋ชป๋ ์ ์์ต๋๋ค).- React๊ฐ ์ด ํดํ์ DOM์ ๋ฐฐ์นํ๊ณ
useLayoutEffect์์ ์ฝ๋๋ฅผ ์คํํฉ๋๋ค. useLayoutEffect๊ฐ ํดํ์ ๋์ด๋ฅผ ๊ณ์ฐํ๊ณ ๋ฐ๋ก ๋ค์ ๋ ๋๋ง์ํต๋๋ค.Tooltip์ด ์ค์ tooltipHeight๋ก ๋ ๋๋ง ๋ฉ๋๋ค. (๋ฐ๋ผ์ ํดํ์ด ์ฌ๋ฐ๋ฅธ ์์น์ ๋ฐฐ์น๋ฉ๋๋ค.)- React๊ฐ DOM์์ ์ด๋ฅผ ์ ๋ฐ์ดํธํ๊ณ ๋ง์นจ๋ด ๋ธ๋ผ์ฐ์ ๊ฐ ํดํ์ ํ์ํฉ๋๋ค.
์๋์ ๋ฒํผ๋ค ์๋ก ๋ง์ฐ์ค ์ปค์๋ฅผ ์ฌ๋ ค์ ํดํ์ด ๊ณต๊ฐ์ ๋ค์ด๊ฐ๋์ง์ ๋ฐ๋ผ ์์น๋ฅผ ์กฐ์ ํ๋ ๊ฒ์ ํ์ธํ์ธ์.
import { useRef, useLayoutEffect, useState } from 'react'; import { createPortal } from 'react-dom'; import TooltipContainer from './TooltipContainer.js'; export default function Tooltip({ children, targetRect }) { const ref = useRef(null); const [tooltipHeight, setTooltipHeight] = useState(0); useLayoutEffect(() => { const { height } = ref.current.getBoundingClientRect(); setTooltipHeight(height); console.log('Measured tooltip height: ' + height); }, []); let tooltipX = 0; let tooltipY = 0; if (targetRect !== null) { tooltipX = targetRect.left; tooltipY = targetRect.top - tooltipHeight; if (tooltipY < 0) { // ์์ชฝ ๊ณต๊ฐ์ ๋ค์ด๊ฐ์ง ๋ชปํ๋ฏ๋ก ์๋์ ๋ฐฐ์นํฉ๋๋ค. tooltipY = targetRect.bottom; } } return createPortal( <TooltipContainer x={tooltipX} y={tooltipY} contentRef={ref}> {children} </TooltipContainer>, document.body ); }
Tooltip ์ปดํฌ๋ํธ๋ ๋ ๋ฒ์ ๋ ๋๋ง์ ๊ฑฐ์น์ง๋ง (์ฒ์์ 0์ผ๋ก ์ด๊ธฐํ๋ tooltipHeight๋ก ๋ ๋๋ง ๋๊ณ , ๊ทธ๋ค์ ์ค์ ๋ก ๊ณ์ฐ๋ ๋์ด๋ก ๋ ๋๋ง ๋จ), ์ค์ ๋ก ๋ณด์ด๋ ๊ฑด ์ต์ข
๊ฒฐ๊ณผ๋ฟ์
๋๋ค. ์ด ์์์์ useEffect ๋์ useLayoutEffect๊ฐ ํ์ํ ์ด์ ์
๋๋ค. ์๋์์ ์ฐจ์ด์ ์ ์์ธํ๊ฒ ์ดํด๋ด
์๋ค.
์์ 1 of 2: useLayoutEffect ๋ ๋ธ๋ผ์ฐ์ ๊ฐ ํ๋ฉด์ ๋ค์ ๊ทธ๋ฆฌ๋ ๊ฒ์ ๋ง์ต๋๋ค
React๋ useLayoutEffect ๋ด๋ถ์ ์ฝ๋์ ์ด๋ก ์ธํ ๋ชจ๋ state ์
๋ฐ์ดํธ๊ฐ ๋ธ๋ผ์ฐ์ ๊ฐ ํ๋ฉด์ ๋ค์ ๊ทธ๋ฆฌ๊ธฐ ์ ์ ์ฒ๋ฆฌ๋๋ ๊ฒ์ ๋ณด์ฅํฉ๋๋ค. ๋๋ถ์ ํดํ์ ๋ ๋๋งํ๊ณ , ์์น์ ํฌ๊ธฐ๋ฅผ ๊ณ์ฐํ๊ณ ๋ค์ ๋ ๋๋งํ๋ฉด์ ์ฒซ ๋ฒ์งธ ๋ ๋๋ง์ ์ฌ์ฉ์๊ฐ ๋ชจ๋ฅด๊ฒ ํ ์ ์์ต๋๋ค. ์ฆ, useLayoutEffect๋ ๋ธ๋ผ์ฐ์ ๊ฐ ํ๋ฉด์ ๊ทธ๋ฆฌ๋ ๊ฒ์ ๋ง์ต๋๋ค.
import { useRef, useLayoutEffect, useState } from 'react'; import { createPortal } from 'react-dom'; import TooltipContainer from './TooltipContainer.js'; export default function Tooltip({ children, targetRect }) { const ref = useRef(null); const [tooltipHeight, setTooltipHeight] = useState(0); useLayoutEffect(() => { const { height } = ref.current.getBoundingClientRect(); setTooltipHeight(height); }, []); let tooltipX = 0; let tooltipY = 0; if (targetRect !== null) { tooltipX = targetRect.left; tooltipY = targetRect.top - tooltipHeight; if (tooltipY < 0) { // ์์ชฝ ๊ณต๊ฐ์ ๋ค์ด๊ฐ์ง ๋ชปํ๋ฏ๋ก ์๋์ ๋ฐฐ์นํฉ๋๋ค. tooltipY = targetRect.bottom; } } return createPortal( <TooltipContainer x={tooltipX} y={tooltipY} contentRef={ref}> {children} </TooltipContainer>, document.body ); }
๋ฌธ์ ํด๊ฒฐ
์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: โuseLayoutEffect does nothing on the serverโ
useLayoutEffect์ ๋ชฉ์ ์ ๋ ์ด์์ ์ ๋ณด๋ฅผ ์ฌ์ฉํด์ ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ๋ ๊ฒ์
๋๋ค.
- ์ด๊ธฐ ์ฝํ ์ธ ๋ฅผ ๋ ๋๋งํฉ๋๋ค.
- ๋ธ๋ผ์ฐ์ ๊ฐ ํ๋ฉด์ ๋ค์ ๊ทธ๋ฆฌ๊ธฐ ์ ์ ๋ ์ด์์์ ๊ณ์ฐํฉ๋๋ค.
- ์ฝ์ ๋ ์ด์์ ์ ๋ณด๋ฅผ ์ฌ์ฉํด์ ์ต์ข ์ฝํ ์ธ ๋ฅผ ๋ ๋๋งํฉ๋๋ค.
์๋ฒ ๋ ๋๋ง์ ์ง์ ์ฌ์ฉํ๊ฑฐ๋ ํ๋ ์์ํฌ์์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ผ๋ฉด, React ์ฑ์ ์๋ฒ์์ ์ด๊ธฐ ๋ ๋๋ง์ ํด์ HTML์ ๋ง๋ญ๋๋ค. ์ด๋ฅผ ํตํด JavaScript ์ฝ๋๊ฐ ๋ก๋๋๊ธฐ ์ ์ ์ด๊ธฐ HTML์ ๋ณด์ฌ์ฃผ๊ฒ ๋ฉ๋๋ค.
๋ฌธ์ ๋ ์๋ฒ์๋ ๋ ์ด์์ ์ ๋ณด๊ฐ ์๋ค๋ ๊ฒ์ ๋๋ค.
์์ ์์์์ Tooltip ์ปดํฌ๋ํธ์์ useLayoutEffect๋ฅผ ํธ์ถํ์ฌ ํดํ์ ์ฝํ
์ธ ์ ๋์ด์ ๋ฐ๋ผ (์ฝํ
์ธ ์ ์์ชฝ๊ณผ ์๋์ชฝ ์ค) ์ฌ๋ฐ๋ฅธ ์์น์ ๋ฐฐ์นํฉ๋๋ค. ์ด๊ธฐ ์๋ฒ HTML์ ์ผ๋ถ๋ก Tooltip์ ๋ ๋๋งํ๋ ค ํ๋ฉด, ์ด๋๋ ํดํ์ ์์น๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ๊ฒฐ์ ํ ์ ์์ ๊ฒ์
๋๋ค. ์๋ฒ์์๋ ์์ง ๋ ์ด์์ ์ ๋ณด๊ฐ ์์ผ๋๊น์! ๋ฐ๋ผ์ ํดํ์ ์๋ฒ์์ ๋ ๋๋งํ๊ธฐ๋ฅผ ์ํ๋๋ผ๋, ํด๋ผ์ด์ธํธ๋ก ์ฎ๊ฒจ์ ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ๋ก๋๋๊ณ ์คํ๋ ํ์ ๋ ๋๋งํด์ผ ํฉ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ๋ ์ด์์ ์ ๋ณด์ ์์กดํ๋ ์ปดํฌ๋ํธ๋ ์ด์ฐจํผ ์๋ฒ์์ ๋ ๋๋งํ ํ์๊ฐ ์์ต๋๋ค. ์๋ฅผ ๋ค๋ฉด, ์ด๊ธฐ ๋ ๋๋ง ์ค์ Tooltip์ด ๋ณด์ด๋ ๊ฒ์ ๋ง์ด ์ ๋ฉ๋๋ค. Tooltip์ ํด๋ผ์ด์ธํธ ์ํธ์์ฉ์ ์ํด์ ๋ณด์ด๋ ๊ฒ์ด๋๊น์.
๊ทธ๋ผ์๋ ์ด๋ฐ ๋ฌธ์ ๋ฅผ ๋ง์ฃผ์น๋ค๋ฉด ๋ช ๊ฐ์ง ๋ค๋ฅธ ์ต์ ์ด ์์ต๋๋ค.
-
useLayoutEffect๋ฅผuseEffect๋ก ๋์ฒด ํ์ธ์. ํ๋ฉด์ ๊ทธ๋ฆฌ๋ ๊ฒ์ ๋ง์ง ๋ง๊ณ (์ด๊ธฐ HTML์ด Effect ์คํ ์ ์ ๋ณด์ด๊ธฐ ๋๋ฌธ์) ์ด๊ธฐ ๋ ๋๋ง์ด ๋ณด์ด๋๋ผ๋ ๊ด์ฐฎ๋ค๊ณ React์๊ฒ ๋งํด์ฃผ๋ ๊ฒ์ ๋๋ค. -
๋๋ ํด๋น ์ปดํฌ๋ํธ๋ฅผ ํด๋ผ์ด์ธํธ ์ ์ฉ์ผ๋ก ๋ง๋์ธ์. React๊ฐ ๊ฐ์ฅ ๊ฐ๊น์ด
<Suspense>๊ฒฝ๊ณ ์์ ์ฝํ ์ธ ๋ฅผ ์๋ฒ๋ ๋๋ง ๋์ (์คํผ๋๋ ๊ธ๋ฆฌ๋จธ๊ฐ์) loading fallbck์ผ๋ก ๋์ฒด ํ๊ฒ ํฉ๋๋ค. -
๋๋
useLayoutEffect๊ฐ ์๋ ์ปดํฌ๋ํธ๋ฅผ hydration ์ดํ์๋ง ๋ ๋๋งํ ์๋ ์์ต๋๋ค. ๋ถ๋ฆฌ์ธ ํ์ ์ธisMountedstate๋ฅผ ์ด๊น๊ฐ์ธfalse๋ก ์ ์งํ๋ค๊ฐ,useEffectํธ์ถ๋๋ฉด ๊ฑฐ๊ธฐ์true๋ก ๊ฐ์ ๋ณ๊ฒฝํ์ธ์. ๊ทธ๋ฌ๋ฉด ๋ ๋๋ง ๋ก์ง์return isMounted ? <RealContent /> : <FallbackContent />์ฒ๋ผ ๋ ์ ์์ต๋๋ค. ์๋ฒ์์ ๋ ๋๋งํ๋ ์ค์ด๊ฑฐ๋ hydration ๋์ ์ฌ์ฉ์๋FallbackContent๋ฅผ ๋ณผ ๊ฒ์ด๊ณFallbackContent๋useLayoutEffect๋ฅผ ํธ์ถํ์ง ์์์ผ ํฉ๋๋ค. ๊ทธ ํ์ React๊ฐFallbackContent๋ฅผ ํด๋ผ์ด์ธํธ ์ ์ฉ์ด๋ฉด์useLayoutEffect๋ฅผ ํธ์ถํ๋RealContent๋ก ๋ณ๊ฒฝํ ๊ฒ๋๋ค. -
์ปดํฌ๋ํธ๋ฅผ ์ธ๋ถ ๋ฐ์ดํฐ ์ ์ฅ์์ ๋๊ธฐํํ๊ณ , ๋ ์ด์์ ๊ณ์ฐ ์ธ์ ๋ค๋ฅธ ์ด์ ๋ก
useLayoutEffect์ ์์กดํ๋ ๊ฒฝ์ฐ๋ผ๋ฉด, ๋์useSyncExternalStore๋ฅผ ๊ณ ๋ คํด ๋ณด์ธ์. ์ด Hook์ ์๋ฒ ๋ ๋๋ง์ ์ง์ํฉ๋๋ค.