๐ŸŽฏ 21. useEffect vs useLayoutEffect โ€” ์ด ๋‘˜์˜ ์ง„์งœ ์ฐจ์ด, ์ด์ œ๋Š” ๋ช…ํ™•ํ•˜๊ฒŒ ์•Œ๊ณ  ์‹ถ์—ˆ๋‹ค

JM_Devยท2025๋…„ 5์›” 2์ผ
0
post-thumbnail

React์—์„œ ์ƒํƒœ๋‚˜ DOM ๋ณ€๊ฒฝ ํ›„์— ์‹คํ–‰ํ•  ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ฅผ ์ค„ ๋•Œ
์šฐ๋ฆฌ๋Š” ๋ณดํ†ต useEffect๋ฅผ ๋งŽ์ด ์“ฐ๋Š”๋ฐ,
๋น„์Šทํ•œ ์ด๋ฆ„์˜ useLayoutEffect๋„ ์žˆ๊ณ , ์–ธ์ œ ์–ด๋–ค ๊ฑธ ์จ์•ผ ํ• ์ง€ ๊ณ ๋ฏผ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์•˜๋‹ค.

๊ทธ๋ž˜์„œ ์ด๋ฒˆ์—” ์‹ค์ œ ์ฐจ์ด์ ๊ณผ ์‚ฌ์šฉ ๊ธฐ์ค€์„ ์ •๋ฆฌํ•ด๋ดค๋‹ค.


๐Ÿง  ๊ธฐ๋ณธ ๊ฐœ๋… ๋จผ์ € ์ •๋ฆฌ

Hook์‹คํ–‰ ํƒ€์ด๋ฐ
useEffect๋ Œ๋”๋ง ๊ฒฐ๊ณผ๊ฐ€ ์‹ค์ œ๋กœ ํ™”๋ฉด์— ๋ฐ˜์˜๋œ ํ›„ ์‹คํ–‰
useLayoutEffect๋ Œ๋”๋ง์ด ์™„๋ฃŒ๋˜๊ธฐ ์ง์ „, DOM์ด ๊ทธ๋ ค์ง€๊ธฐ ์ „ ์‹คํ–‰

์ฆ‰, useLayoutEffect๋Š” ์‹œ๊ฐ์ ์œผ๋กœ ๊ทธ๋ ค์ง€๊ธฐ ์ „์— DOM ์กฐ์ž‘์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒŒ ํ•ต์‹ฌ์ด๋‹ค.


โœ… ์ฝ”๋“œ ํ๋ฆ„์œผ๋กœ ์ดํ•ดํ•˜๊ธฐ

function MyComponent() {
  useEffect(() => {
    console.log('โœ… useEffect ์‹คํ–‰');
  });

  useLayoutEffect(() => {
    console.log('โš ๏ธ useLayoutEffect ์‹คํ–‰');
  });

  return <div>๋ Œ๋”๋ง ์ค‘...</div>;
}

์ถœ๋ ฅ ์ˆœ์„œ:

โš ๏ธ useLayoutEffect ์‹คํ–‰  
โœ… useEffect ์‹คํ–‰
  • ๋‘˜ ๋‹ค ๋งˆ์šดํŠธ ์ดํ›„ ์‹คํ–‰๋˜์ง€๋งŒ,
  • useLayoutEffect๊ฐ€ ๋จผ์ € ์‹คํ–‰๋˜๊ณ  โ†’ ๊ทธ ๋‹ค์Œ์— ํ™”๋ฉด์ด ๊ทธ๋ ค์ง โ†’ ๊ทธ ์ดํ›„ useEffect

๐Ÿ” ์–ธ์ œ useLayoutEffect๋ฅผ ์จ์•ผ ํ• ๊นŒ?

useLayoutEffect๋Š” ๋‹ค์Œ์ฒ˜๋Ÿผ ํ™”๋ฉด์ด ๊ทธ๋ ค์ง€๊ธฐ ์ „์— ๋ ˆ์ด์•„์›ƒ ์กฐ์ •์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์จ์•ผ ํ•œ๋‹ค.

โœ… ์“ฐ๋Š” ๊ฒŒ ๋งž๋Š” ์ƒํ™ฉ

  • DOM์˜ ํฌ๊ธฐ, ์œ„์น˜ ๊ณ„์‚ฐ ํ›„ ์œ„์น˜ ์ด๋™ (์˜ˆ: ํˆดํŒ ์œ„์น˜ ๊ณ„์‚ฐ)
  • ์Šคํฌ๋กค ์œ„์น˜ ๊ฐ•์ œ ์กฐ์ •
  • ์ฒซ ๋ Œ๋”๋ง์—์„œ ๊นœ๋นก์ž„ ๋ฐฉ์ง€
useLayoutEffect(() => {
  const width = boxRef.current.offsetWidth;
  boxRef.current.style.left = `${width / 2}px`;
}, []);

โŒ ์ž˜๋ชป ์“ฐ๋ฉด ์„ฑ๋Šฅ ์ด์Šˆ

useLayoutEffect๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ™”๋ฉด ๊ทธ๋ฆฌ๊ธฐ(painting)๋ฅผ ๋ฉˆ์ถ”๊ณ  ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ๋œ๋‹ค.

๊ทธ๋ž˜์„œ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด ๋ Œ๋”๋ง์ด ๋А๋ ค์ง€๊ณ ,
ํŠนํžˆ ๋ชจ๋ฐ”์ผ ๊ธฐ๊ธฐ์—์„œ๋Š” ํ”„๋ ˆ์ž„ ๋“œ๋ž์ด ์ƒ๊ธฐ๊ธฐ๋„ ํ•œ๋‹ค.


โœ… ๋Œ€๋ถ€๋ถ„์€ useEffect๋กœ ์ถฉ๋ถ„ํ•˜๋‹ค

useEffect(() => {
  document.title = 'ํŽ˜์ด์ง€ ์ œ๋ชฉ ๋ฐ”๊พธ๊ธฐ';
}, []);
  • ์„œ๋ฒ„ ๋ฐ์ดํ„ฐ ์š”์ฒญ
  • ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ๋“ฑ๋ก
  • ๋กœ๊ทธ ์ถœ๋ ฅ, ์•Œ๋ฆผ ๋ฐœ์ƒ ๋“ฑ
    โ†’ ์ด๋Ÿฐ ๊ฒƒ๋“ค์€ ์ „๋ถ€ useEffect๋กœ ์ฒ˜๋ฆฌํ•˜๋ฉด ์ถฉ๋ถ„ํ•˜๋‹ค.

โœ๏ธ ์š”์•ฝ ๋น„๊ต

ํ•ญ๋ชฉuseEffectuseLayoutEffect
์‹คํ–‰ ์‹œ์ ํ™”๋ฉด ๊ทธ๋ ค์ง„ ํ›„ํ™”๋ฉด ๊ทธ๋ ค์ง€๊ธฐ ์ง์ „
๋น„๋™๊ธฐ ์—ฌ๋ถ€๋น„๋™๊ธฐ์ ๋™๊ธฐ์ 
์„ฑ๋Šฅ ์˜ํ–ฅ๊ฑฐ์˜ ์—†์Œ์ฃผ์˜ ํ•„์š” (๋ Œ๋”๋ง ๋ธ”๋กœํ‚น)
์ฃผ ์‚ฌ์šฉ ๋ชฉ์ ๋ฐ์ดํ„ฐ ํŒจ์นญ, ๋ฆฌ์Šค๋„ˆ ๋“ฑ๋ก ๋“ฑDOM ์œ„์น˜, ์‚ฌ์ด์ฆˆ ์กฐ์ •

๐Ÿ“ ๋‚ด๊ฐ€ ๋А๋‚€ ์ 

๊ฐœ์ธ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” useEffect๋งŒ์œผ๋กœ๋„ ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.
๊ทธ๋Ÿฐ๋ฐ ํˆดํŒ UI๋ฅผ ๋งŒ๋“ค๋ฉด์„œ useLayoutEffect๋กœ ์œ„์น˜ ๊ณ„์‚ฐ์„ ์•ˆ ํ•˜๋ฉด
ํˆดํŒ์ด ๊นœ๋นก์ด๋ฉฐ ์›€์ง์ด๋Š” ํ˜„์ƒ์ด ์ƒ๊ฒผ๊ณ ,
๊ทธ์ œ์•ผ "์•„ ์ด๊ฒŒ ๊ทธ๋ ค์ง€๊ธฐ ์ „์— ์‹คํ–‰๋ผ์•ผ ํ•˜๋Š” ๊ฑฐ๊ตฌ๋‚˜" ํ•˜๊ณ  ์‹ค๊ฐํ–ˆ๋‹ค.

์ด์ œ๋Š” โ€œ์ •๋ง DOM ๊ณ„์‚ฐ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ useLayoutEffect๋ฅผ ์“ฐ์žโ€๋Š” ์›์น™์ด ์ƒ๊ฒผ๋‹ค.


๐Ÿงฉ "๋‘˜ ๋‹ค ์ดํŽ™ํŠธ์ง€๋งŒ, '์–ธ์ œ ์‹คํ–‰๋˜๋А๋ƒ'๋Š” ์ „ํ˜€ ๋‹ค๋ฅด๋‹ค."

profile
๊ฐœ๋ฐœ์ž๋กœ ์ทจ์—…์„ ์ค€๋น„ ์ค‘ ์ด๋ฉฐ, ์—ด์‹ฌํžˆ ๊ณต๋ถ€ ์ค‘ ์ž…๋‹ˆ๋‹ค!

0๊ฐœ์˜ ๋Œ“๊ธ€