๐Ÿ˜‰

10. useLayoutEffect

ย 
ย 

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๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.
(์ฐธ๊ณ ) ์ผ๋ฐ˜์ ์œผ๋กœ useEffect๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.
  1. ๋ฐ์ดํ„ฐ๋ฅผ ๋น„๋™๊ธฐ๋กœ ๋ฐ›์•„์˜ฌ ๋•Œ (fetch)
  1. event handler๋ฅผ ์ ์šฉํ•  ๋•Œ
  1. 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์˜ ์‹คํ–‰ ์ˆœ์„œ ์ฐจ์ด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ย 
๊ทธ๋ฆผ 10-1 ์ปดํฌ๋„ŒํŠธ์˜ ์ƒ๋ช…์ฃผ๊ธฐ๊ทธ๋ฆผ 10-1 ์ปดํฌ๋„ŒํŠธ์˜ ์ƒ๋ช…์ฃผ๊ธฐ
๊ทธ๋ฆผ 10-1 ์ปดํฌ๋„ŒํŠธ์˜ ์ƒ๋ช…์ฃผ๊ธฐ
ย 
useEffect๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”์™€ ํŽ˜์ธํŠธ ๊ณผ์ •์ด ๋ชจ๋‘ ๋๋‚œ ๋’ค์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ useEffect ํ•จ์ˆ˜ ๋‚ด๋ถ€์— DOM์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ์ฝ”๋“œ๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ๋ฆฌ๋ Œ๋”๋ง ๋˜๋ฉด์„œ ํ™”๋ฉด์˜ ๊นœ๋นก์ž„ ํ˜„์ƒ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฐ˜๋ฉด์— useLayoutEffect๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์— ํŽ˜์ธํŠธ ๋˜๊ธฐ ์ „์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, useLayoutEffect ๋‚ด๋ถ€์˜ ์ฝ”๋“œ๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ง€๊ธฐ ์ „์— ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ํ™”๋ฉด์˜ ๊นœ๋นก์ž„ ํ˜„์ƒ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค.
ย 
useLayoutEffect vsย useEffect ์‹คํ–‰ ์ˆœ์„œ ๋น„๊ต
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์˜ ์‹คํ–‰ ์ˆœ์„œ ๋น„๊ต
ย 
useEffect์™€ useLayoutEffect๋ฅผ ๋™์‹œ์— ์‚ฌ์šฉํ•˜๋ฉด ์‹คํ–‰ ์ˆœ์„œ์˜ ์ฐจ์ด๋กœ ์ธํ•ด ๋‚˜์ค‘์— ์ž‘์„ฑํ•œ useLayoutEffect๊ฐ€ ๋จผ์ € ์ฝ˜์†”์— ์ฐํžˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ย 
ย 
๊ทธ๋ฆผ 10-2 ์ฝ”๋“œ ์‹คํ–‰ ํ™”๋ฉด๊ทธ๋ฆผ 10-2 ์ฝ”๋“œ ์‹คํ–‰ ํ™”๋ฉด
๊ทธ๋ฆผ 10-2 ์ฝ”๋“œ ์‹คํ–‰ ํ™”๋ฉด
ย 
๋”ฐ๋ผ์„œ 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์œผ๋กœ ๋ณด์—ฌ์ง€๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ย 
๊ทธ๋ฆผ 10-3 ์ฝ”๋“œ ์‹คํ–‰ ํ™”๋ฉด๊ทธ๋ฆผ 10-3 ์ฝ”๋“œ ์‹คํ–‰ ํ™”๋ฉด
๊ทธ๋ฆผ 10-3 ์ฝ”๋“œ ์‹คํ–‰ ํ™”๋ฉด
ย 
์ปดํฌ๋„ŒํŠธ ๋ Œ๋” ๊ณผ์ • ๋‹ค์Œ์— useLayoutEffect๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ณ€๊ฒฝ ๋‚ด์—ญ์„ ํ™”๋ฉด์— ๊ทธ๋ฆฌ๊ธฐ ์ „์— ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋™๊ธฐ์ ์œผ๋กœ useLayoutEffect๊ฐ€ ์‹คํ–‰์ด ๋๋‚˜๊ณ  ๋‚œ ํ›„ ๋ธŒ๋ผ์šฐ์ €์— ํŽ˜์ธํŠธํ•˜์—ฌ ์•„๋ž˜ ๊ทธ๋ฆผ 10-4 ์ฒ˜๋Ÿผ number2์˜ ์ƒํƒœ๊ฐ€ 181๋กœ ๋ฐ”๋€Œ๊ณ  useEffect๋Š” ์•„์ง ์‹คํ–‰๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— 0์ธ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ย 
๊ทธ๋ฆผ 10-4 ์ฝ”๋“œ ์‹คํ–‰ ํ™”๋ฉด๊ทธ๋ฆผ 10-4 ์ฝ”๋“œ ์‹คํ–‰ ํ™”๋ฉด
๊ทธ๋ฆผ 10-4 ์ฝ”๋“œ ์‹คํ–‰ ํ™”๋ฉด
ย 
๋‹ค์Œ์œผ๋กœ useEffect๊ฐ€ ํ˜ธ์ถœ๋˜์–ด number1์˜ ์ƒํƒœ๊ฐ’์€ 3์œผ๋กœ ๋ฐ”๋€Œ๊ณ  ์•„๋ž˜ ๊ทธ๋ฆผ 10-5์ฒ˜๋Ÿผ ๋‚˜ํƒ€๋‚˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
ย 
๊ทธ๋ฆผ 10-5 ์ฝ”๋“œ ์‹คํ–‰ ํ™”๋ฉด๊ทธ๋ฆผ 10-5 ์ฝ”๋“œ ์‹คํ–‰ ํ™”๋ฉด
๊ทธ๋ฆผ 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;
(์˜ˆ์ œ) ์‚ฌ๊ฐํ˜• ํฌ๊ธฐ ๋ณ€๊ฒฝํ•˜๊ธฐ
ย 
๊ทธ๋ฆผ 10-6 ์˜ˆ์ œ ์ฝ”๋“œ ์‹คํ–‰ ๊ณผ์ • 3๋‹จ๊ณ„๊ทธ๋ฆผ 10-6 ์˜ˆ์ œ ์ฝ”๋“œ ์‹คํ–‰ ๊ณผ์ • 3๋‹จ๊ณ„
๊ทธ๋ฆผ 10-6 ์˜ˆ์ œ ์ฝ”๋“œ ์‹คํ–‰ ๊ณผ์ • 3๋‹จ๊ณ„
ย 
์œ„์˜ ์ฝ”๋“œ์—์„œ๋Š” 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๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ย 
ย 
ย 
ย 
ย 
ย 
ย