ย
10.1 useLayoutEffect๋?10.1.1 useLayoutEffect ๊ฐ๋
10.2 useLayoutEffect๋ฅผ ์ฌ์ฉํ๋ ์ด์ 10.2.1 useLayoutEffect ์ฌ์ฉ ์ ์ฃผ์์ฌํญ10.3 useEffect vs useLayoutEffect10.3.1 useEffect์ useLayoutEffect์ ์ฐจ์ด์ 10.3.2 (์ค์ต1) useLayoutEffect์ useEffect ๋น๊ต10.3.3 (์ค์ต2) useLayoutEffect์ useEffect ๋น๊ต
ย
10.1 useLayoutEffect๋?
useLayoutEffect๋ย ์์ ์ดํด๋ณธ useEffect์ ๊ฑฐ์ ๋น์ทํ ๊ธฐ๋ฅ์ ํ๋ Hook์
๋๋ค. ์ด๋ฒ ์ฑํฐ์์๋ ๋ ๊ฐ์ง Hook์ ์ด๋ป๊ฒ ๊ตฌ๋ถํด์ ์จ์ผ ํ๋์ง๋ฅผ ์์ฃผ๋ก ์ดํด๋ณด๊ฒ ์ต๋๋ค.
ย
10.1.1 useLayoutEffect ๊ฐ๋
useLayoutEffect๋ React ์ปดํฌ๋ํธ๊ฐ ๋ ๋(Render) ๊ณผ์ ์ ๊ฑฐ์น ๋ค, ๋๊ธฐ์ (synchronous)์ผ๋ก ์คํ๋ฉ๋๋ค. ์ปดํฌ๋ํธ๊ฐ ๋ธ๋ผ์ฐ์ ์ ํ์ธํธ(Paint) ๋๊ธฐ ์ ์ ์คํ๋๊ธฐ ๋๋ฌธ์ DOM์์ ๋ ์ด์์์ ์ฝ๊ณ ๋๊ธฐ์ ์ผ๋ก ๋ฆฌ๋ ๋๋งํ๋ ๊ฒฝ์ฐ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ ํฉํฉ๋๋ค. useLayoutEffect๋ฅผ ์ ์ ํ๊ฒ ์ฌ์ฉํ๋ฉด ์ฌ์ฉ์ ํธ์๋ฅผ ๊ฐ์ ํ ์ ์์ต๋๋ค.
ย
ย
10.2 useLayoutEffect๋ฅผ ์ฌ์ฉํ๋ ์ด์
์ผ๋ฐ์ ์ผ๋ก state๊ฐ ์กฐ๊ฑด์ ๋ฐ๋ผ ์ฒซ ํ์ธํธ ๊ณผ์ ์์๋ถํฐ ๋ณด์ฌ์ ธ์ผ ํ ๋ useLayoutEffect๋ฅผ ์ฌ์ฉํ๋ฉด ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ๋น์ทํ ๋์์ ํ๋ useEffect๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด ์ฒซ ํ์ธํ
์์ state๊ฐ ์ํ๋ ๊ฐ์ด ์๋ ์ด๊น๊ฐ์ผ๋ก ๋ ๋๋ง ๋๊ณ , ๋ฆฌ๋ ๋๋ง ๋๋ฉด์ ํ๋ฉด์ด ๊น๋นก๊ฑฐ๋ฆฌ๋ ํ์์ด ๋ฐ์ํ ์ ์์ต๋๋ค.
์ด๋ฌํ ๊น๋นก๊ฑฐ๋ฆฌ๋ ํ์์ ๋ฐฉ์งํ๊ณ ์ ํ ๋ useLayoutEffect๋ฅผ ์ฌ์ฉํฉ๋๋ค. useEffect์ useLayoutEffect์ ์ฐจ์ด์ ์ 10.3์์ ์์ธํ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
ย
(์ฐธ๊ณ ) ์ผ๋ฐ์ ์ผ๋ก
useEffect
๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ ์๋์ ๊ฐ์ต๋๋ค.- ๋ฐ์ดํฐ๋ฅผ ๋น๋๊ธฐ๋ก ๋ฐ์์ฌ ๋ (fetch)
- event handler๋ฅผ ์ ์ฉํ ๋
- state๋ฅผ ๋ฆฌ์ ํ ๋
ย
10.2.1 useLayoutEffect ์ฌ์ฉ ์ ์ฃผ์์ฌํญ
SSR(Server-Side Rendering) ํ๊ฒฝ์์ useLayoutEffect๋ฅผ ์ฌ์ฉํ๋ฉด ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ๋ชจ๋ ์คํ๋๊ธฐ ์ ๊น์ง useLayoutEffect๋ ์๋ฒ ๋ ๋๋ฌ์ ์ถ๋ ฅํ์์ผ๋ก ์ธ์ฝ๋ฉํ ์ ์๊ธฐ ๋๋ฌธ์ ์๋ฒ์์ ์๋ฌด ์์
๋ ์ํํ์ง ๋ชปํฉ๋๋ค. ๋ฐ๋ผ์ ์๋ํ๋ UI์ ์ผ์นํ์ง ์๋ ํ์์ด ๋ฐ์ํฉ๋๋ค. ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ์ฌ์ ์ ๋ฐฉ์งํ๊ธฐ ์ํดย 'ํด๋ผ์ด์ธํธ'์์ ๋ ๋๋งํ๋ ์ปดํฌ๋ํธ์์๋งย useLayoutEffect๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
๋ํ, useLayoutEffect๋ย ๋๊ธฐ์ ์ผ๋ก ์คํ๋๊ธฐ ๋๋ฌธ์ ๋ด๋ถ์ ์๋ฒ์์ ๋ถ๋ฌ์ค๋ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ ์์
์ด ์๊ฑฐ๋ ๋ด๋ถ์ ๋ก์ง์ด ๋ณต์กํ ๊ฒฝ์ฐ ๋ ์ด์์์ด ๋ธ๋ผ์ฐ์ ์ ๋ณด์ฌ์ง๊ธฐ๊น์ง ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฐ๋ค๋ ๋จ์ ์ด ์์ต๋๋ค. ์ํฉ์ ๋ฐ๋ผ useLayoutEffect๋ฅผ ์ ์ ํ๊ฒ ์ฌ์ฉํด์ผํ๋ฉฐ ๊ธฐ๋ณธ์ ์ผ๋ก useEffect๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค.
ย
์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง(SSR, Server Side Rendering)์
์๋ฒ์์ ์์ฑ๋ html ํ์ผ์ ๋ง๋ค์ด์ ํด๋ผ์ด์ธํธ์๊ฒ ๋ณด์ฌ์ฃผ๋ ๋ฐฉ์์
๋๋ค.
๋ฐ๋๋ก ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ ๋๋ง(CSR, Client Side Rendering)์ ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ๋์ ์ผ๋ก html์ ์ง์ ๋ง๋ค์ด ๋ณด์ฌ์ฃผ๋ ๋ฐฉ์์
๋๋ค.
ย
10.3 useEffect vs useLayoutEffect
10.3.1 useEffect์ useLayoutEffect์ ์ฐจ์ด์
useLayoutEffect์ useEffect๋ ์คํ๋๋ ์์์์ ์ฐจ์ด๊ฐ ์์ต๋๋ค.
React๋ React DOM ํธ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ๊ธฐ ์ํ ๋ ๋์ ์ค์ ๋ธ๋ผ์ฐ์ ์ ๊ทธ๋ ค์ฃผ๋ ํ์ธํธ ๊ณผ์ ์ ๊ฑฐ์ณ ์ปดํฌ๋ํธ๋ฅผ ๋ธ๋ผ์ฐ์ ์ ๋ ๋๋งํฉ๋๋ค. ์๋๋ useEffect ์ฑํฐ์์ ์ค๋ช
ํ๋ ์ปดํฌ๋ํธ์ ์๋ช
์ฃผ๊ธฐ ๊ด๋ จ ์ด๋ฏธ์ง์
๋๋ค. ์ปดํฌ๋ํธ์ ์
๋ฐ์ดํธ ๋จ๊ณ์์ ๋ ๋์ ํ์ธํธ ๊ณผ์ ์ ๊ธฐ์ค์ผ๋ก ๋ ๊ฐ์ง Hook์ ์คํ ์์ ์ฐจ์ด๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
ย
ย
useEffect๋ ์ปดํฌ๋ํธ์ ๋ ๋์ ํ์ธํธ ๊ณผ์ ์ด ๋ชจ๋ ๋๋ ๋ค์ ์คํ๋ฉ๋๋ค. ๋ฐ๋ผ์ useEffect ํจ์ ๋ด๋ถ์ DOM์ ์ํฅ์ ์ฃผ๋ ์ฝ๋๊ฐ ์์ ๊ฒฝ์ฐ ๋ฆฌ๋ ๋๋ง ๋๋ฉด์ ํ๋ฉด์ ๊น๋นก์ ํ์์ด ๋ฐ์ํ ์ ์์ต๋๋ค.
๋ฐ๋ฉด์ useLayoutEffect๋ ์ปดํฌ๋ํธ๊ฐ ๋ธ๋ผ์ฐ์ ์ ํ์ธํธ ๋๊ธฐ ์ ์ ์คํ๋ฉ๋๋ค. ์ฆ, useLayoutEffect ๋ด๋ถ์ ์ฝ๋๋ ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ง๊ธฐ ์ ์ ์คํ๋๊ธฐ ๋๋ฌธ์ ํ๋ฉด์ ๊น๋นก์ ํ์์ด ๋ฐ์ํ์ง ์๋ ๊ฒ ์
๋๋ค.
ย
useLayoutEffect
vsย useEffect
์คํ ์์ ๋น๊ตuseLayoutEffect
component
โ render
โ useLayoutEffect
โ paint
ย
useEffect
component
โ render
โ paint
โ useEffect
ย
์๋์ ์์ ์ฝ๋๋ก ์ง์ ํ์ธํด๋ด
์๋ค.
ย
import { useEffect, useLayoutEffect } from 'react'; function App() { useEffect(() => { console.log('useEffect ์คํ!'); }, []); useLayoutEffect(() => { console.log('useLayoutEffect ์คํ!'); }, []); return ( <div>์คํ ์์๋ฅผ ํ์ธํด๋ด ์๋ค!</div> ); } export default App;
ย
useEffect์ useLayoutEffect๋ฅผ ๋์์ ์ฌ์ฉํ๋ฉด ์คํ ์์์ ์ฐจ์ด๋ก ์ธํด ๋์ค์ ์์ฑํ useLayoutEffect๊ฐ ๋จผ์ ์ฝ์์ ์ฐํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
ย
ย
ย
๋ฐ๋ผ์ useEffect๋ณด๋ค ๋จผ์ ์คํํ๊ณ ์ถ์ ์ฝ๋๊ฐ ์๋ค๋ฉด useLayoutEffect๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
ย
10.3.2 (์ค์ต1) useLayoutEffect์ useEffect ๋น๊ต
10.3.1์ ์์ useLayoutEffect์ useEffect์ ์คํ ์์ ์ฐจ์ด์ ๋ํด ์ดํด๋ณด์์ต๋๋ค. ์ง๊ธ๋ถํฐ๋ ์์ ์ฝ๋๋ฅผ ํตํด ๋ Hook์ด ์ด๋ป๊ฒ ๋ค๋ฅด๊ฒ ํธ์ถ๋์ด ๋ธ๋ผ์ฐ์ ์ ํ์ธํธํ๋์ง ์ดํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ์๋๋ ๋ ๋๋ง ์ดํ useLayoutEffect์ useEffect๊ฐ ํธ์ถ๋๋ ์์ ์ ์ฐจ์ด๋ฅผ ํ์ธํ๋ ์์ ์ฝ๋์
๋๋ค.
ย
import React, { useState, useLayoutEffect, useEffect} from "react"; function App() { const [number1, setNumber1] = useState(0); const [number2, setNumber2] = useState(0); useEffect(() => { setNumber1(parseInt(Math.random() * 100)); }, []); useLayoutEffect(() => { setNumber2(parseInt(Math.random() * 200)); }, []); console.log("useEffect : ", number1); console.log("useLayoutEffect : ", number2); return ( <div style={{ paddingLeft: '10px' }}> <h1>useEffect: {number1}</h1> <h1>useLayoutEffect: {number2}</h1> </div> ); }; export default App;
ย
์ ์ฝ๋๋ฅผ ์คํํ๋ฉด ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ๋จผ์ ์๋์ ๊ทธ๋ฆผ 10-3์ ์ฝ์์ฐฝ์์ ์ต์ด ๋ ๋๋ง์ด ์ผ์ด๋ number1์ number2์ ์ํ๊ฐ์ด 0์ผ๋ก ๋ณด์ฌ์ง๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
ย
ย
์ปดํฌ๋ํธ ๋ ๋ ๊ณผ์ ๋ค์์ useLayoutEffect๊ฐ ํธ์ถ๋ฉ๋๋ค. ํ์ง๋ง, ๋ธ๋ผ์ฐ์ ๊ฐ ๋ณ๊ฒฝ ๋ด์ญ์ ํ๋ฉด์ ๊ทธ๋ฆฌ๊ธฐ ์ ์ ํธ์ถ๋ฉ๋๋ค. ๋ฐ๋ผ์ ๋๊ธฐ์ ์ผ๋ก useLayoutEffect๊ฐ ์คํ์ด ๋๋๊ณ ๋ ํ ๋ธ๋ผ์ฐ์ ์ ํ์ธํธํ์ฌ ์๋ ๊ทธ๋ฆผ 10-4 ์ฒ๋ผ number2์ ์ํ๊ฐ 181๋ก ๋ฐ๋๊ณ useEffect๋ ์์ง ์คํ๋์ง ์์๊ธฐ ๋๋ฌธ์ 0์ธ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
ย
ย
๋ค์์ผ๋ก useEffect๊ฐ ํธ์ถ๋์ด number1์ ์ํ๊ฐ์ 3์ผ๋ก ๋ฐ๋๊ณ ์๋ ๊ทธ๋ฆผ 10-5์ฒ๋ผ ๋ํ๋๊ฒ ๋ฉ๋๋ค.
ย
ย
์ด๋ ๋ฏ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ์์ useEffect๋ก ์ํ๋ ์์
์ ์ํํ๊ธฐ์ ์ถฉ๋ถํ๊ฒ ์ง๋ง, ๋ธ๋ผ์ฐ์ ์ ํ์ธํธ ๋๊ธฐ ์ ์ ์ํํ๊ธฐ๋ฅผ ์ํ๋ฉด useLayoutEffect๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
ย
10.3.3 (์ค์ต2) useLayoutEffect์ useEffect ๋น๊ต
์์ ์ธ๊ธํ ๋ฐ์ ๊ฐ์ด, useEffect์ useLayoutEffect๋ ์คํ ์์์ ์ฐจ์ด๊ฐ ์์ ๋ฟ๋ง ์๋๋ผ, ๋น๋๊ธฐ์ ์ผ๋ก ์คํ๋๋ useEffect์ ๋ฌ๋ฆฌ useLayoutEffect๋ ๋๊ธฐ์ ์ผ๋ก ์คํ๋๋ค๋ ์ ์์ ์ฐจ์ด๊ฐ ์์ต๋๋ค. ์๋๋ ํด๋ฆญ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๋๋ง๋ค ๋ฐ์ค์ ํฌ๊ธฐ๊ฐ ๋ฆฌ๋ ๋๋ง๋๋ ๊ฒ์ ํ์ธํ๋ ์์ ์ฝ๋์ ์คํ ๊ฒฐ๊ณผ์
๋๋ค.
ย
import { useState, useEffect, useLayoutEffect } from 'react' function App() { const [effectValue, setEffectValue] = useState(100); const [layoutEffectValue, setLayoutEffectValue] = useState(100); useEffect(() => { for (let index = 0; index < 40000; index++) { for (let index2 = 0; index2 < 40000; index2++) { } } if (effectValue >= 250) { setEffectValue(200); } }, [effectValue]); useLayoutEffect(() => { for (let index = 0; index < 40000; index++) { for (let index2 = 0; index2 < 40000; index2++) { } } if (layoutEffectValue >= 250) { setLayoutEffectValue(200); } }, [layoutEffectValue]); return ( <div style={{ padding: '20px' }}> <div style={{ display: 'flex' }}> <div style={{ width: effectValue, height: effectValue, backgroundColor: 'blue' }}> </div> <div style={{ width: layoutEffectValue, height: layoutEffectValue, backgroundColor: 'aqua' }}> </div> </div> <button onClick={() => { setEffectValue(250); setLayoutEffectValue(250); }}> ์ปค์ ธ๋! </button> <button onClick={() => { setEffectValue(150); setLayoutEffectValue(150); }}> ์์์ ธ๋! </button> </div> ) } export default App;
ย
ย
์์ ์ฝ๋์์๋ effectValue, layoutEffectValue 2๊ฐ์ state๋ฅผ ํตํด ๊ฐ๊ฐ ์ฒซ ๋ฒ์งธ, ๋ ๋ฒ์งธ div ์์ญ์ ํฌ๊ธฐ๋ฅผ ๊ฒฐ์ ํ๊ณ ์์ต๋๋ค. useEffect์ useLayoutEffect์์๋ ๊ฐ๊ฐ effectValue, layoutEffectValue 2๊ฐ์ state๋ฅผ ๊ฐ์ํ๊ณ ์์ผ๋ฉฐ, state๋ค์ ํฌ๊ธฐ๊ฐ 250 ์ด์์ผ๋ก ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ, ํด๋น state์ ๊ฐ์ setState๋ฅผ ํตํด 200์ผ๋ก ์กฐ์ ํ๋ ์ญํ ์ ํ๊ณ ์์ต๋๋ค.
ย
โ์ปค์ ธ๋โ ๋ฒํผ์ ํด๋ฆญํ ๊ฒฝ์ฐ, ํด๋น ๋ฒํผ์ ํด๋ฆญ ์ด๋ฒคํธ์ ๋ฑ๋ก๋ ํจ์๊ฐ ์คํ๋๋ฉฐ, effectValue, layoutEffectValue 2๊ฐ์ state์ ๊ฐ์ 250์ผ๋ก ๋ณ๊ฒฝํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ state์ ๊ฐ์ด ๋ณ๊ฒฝ๋์๊ธฐ ๋๋ฌธ์ ๋ ๋๋ง ๋จ๊ณ๋ฅผ ์ํํ๊ฒ ๋ฉ๋๋ค.
ย
์ด๋ useEffect๋ ํ์ธํ
๋จ๊ณ๊ฐ ๋ง๋ฌด๋ฆฌ๋ ํ, ๋น๋๊ธฐ์ ์ผ๋ก ์คํ๋ฉ๋๋ค. ๋๋ฌธ์ ์ด๊ธฐ์ useEffect๊ฐ ์คํ๋๊ธฐ ์ , ์ฒซ ๋ฒ์งธ ํ์ธํ
๋จ๊ณ์์๋ ๊ทธ๋ฆผ 10-6์ 2๋จ๊ณ์ ๊ฐ์ด ์ฒซ ๋ฒ์งธ div์ ํฌ๊ธฐ๊ฐ 250์ธ ์ํ๋ก ํ๋ฉด์ ๊ทธ๋ ค์ง๋๋ค. ํด๋น ๊ณผ์ ์ด ๋๋ ํ, useEffect๊ฐ ์คํ๋๊ณ , useEffect์์ ๊ฐ์ํ๊ณ ์๋ effectValue์ ๊ฐ์ด 250 ์ด์์ด๋ฏ๋ก effectValue๋ฅผ 200์ผ๋ก ๋ณ๊ฒฝํด์ค๋๋ค. ์ดํ state์ ๊ฐ์ด ๋ณ๊ฒฝ๋์์ผ๋ฏ๋ก ๋ค์ ๋ ๋๋ง ๋จ๊ณ๋ฅผ ์ํํ๊ณ , ๊ทธ๋ฆผ 10-6์ 3๋จ๊ณ์ ๊ฐ์ด ์ฒซ ๋ฒ์งธ div์ ํฌ๊ธฐ๊ฐ 200์ผ๋ก ๋ณ๊ฒฝ๋์ด ํ๋ฉด์ ๋ค์ ํ์ธํ
๋ฉ๋๋ค.
ย
๊ทธ๋ ์ง๋ง useLayoutEffect์ ๊ฒฝ์ฐ์๋ ํ์ธํ
๋จ๊ณ๊ฐ ์ํ๋๊ธฐ ์ ์, ๋๊ธฐ์ ์ผ๋ก ์ํ๋๋ฏ๋ก ํด๋น ํ
์ ์คํ์ด ์๋ฃ๋๊ธฐ ์ ๊น์ง ํ์ธํ
๋จ๊ณ๋ ์์ํ์ง ์์ต๋๋ค. useLayoutEffect๊ฐ ์คํ๋ ๋, ๊ฐ์ํ๊ณ ์๋ layoutEffectValue์ ๊ฐ์ด 250 ์ด์์ด๋ฏ๋ก ํด๋น ๊ฐ์ 200์ผ๋ก ๋ณ๊ฒฝํ๊ณ , ๋ ๋๋ง ๋จ๊ณ๊ฐ ๋ค์ ์ํํ๊ฒ ๋ฉ๋๋ค. ์ดํ ๋๋ฒ์งธ div์ ํฌ๊ธฐ๊ฐ 200์ธ ์ํ๋ก ๊ทธ๋ฆผ 10-6์ 2๋จ๊ณ์ ๊ฐ์ด ํ๋ฉด์ ํ์ธํ
๋๊ณ , ํ์ธํ
๋จ๊ณ๊ฐ ๋๋ฌ์ผ๋ฏ๋ก ์์ useEffect๊ฐ ์คํ๋ ์ ์๊ฒ ๋ฉ๋๋ค.
ย
๋ฐ๋ผ์ UI ์๋ฆฌ๋จผํธ์ ๋ชจ์์ ํ๋ฉด์ ํ์ํ๋๋ฐ ์ ๊น์ ๊น๋นก์ ํ์์ด ์กด์ฌํ๋ค๋ฉด useLayoutEffect๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๊ณ ๋ คํด๋ณผ ์ ์์ต๋๋ค.
ย
ย
ย
ย
ย
ย
ย