๐Ÿ“ฆ ์žก๋™์‚ฌ๋‹ˆ

ํ•˜๋‚˜์˜ ํ‚ค์›Œ๋“œ๋ฅผ ์žก๊ณ  ์ข€ ํŽธํ•˜๊ฒŒ ์ •๋ฆฌํ•˜๊ณ  ์‹ถ์–ด ๋งŒ๋“  ์žก๋™์‚ฌ๋‹ˆ

์žก๋™์‚ฌ๋‹ˆ๋Š” ์กฐ์„  ํ›„๊ธฐ ํ•™์ž ์•ˆ์ •๋ณต์ด ํŽธ์ฐฌํ•œ ์žก๋™์‚ฐ์ด(้›œๅŒๆ•ฃ็•ฐ)์—์„œ ์œ ๋ž˜๋œ ๋ง์ด๋‹ค.
์žก๋™์‚ฐ์ด๋Š” ์žก๊ธฐ(้›œ่จ˜)์˜ ํ˜•ํƒœ๋ฅผ ๋นŒ๋ ค์˜จ ์ฑ…์œผ๋กœ ๊ตฌ์ฒด์ ์ธ ์ฒด๊ณ„๊ฐ€ ์žกํ˜€์žˆ์ง€ ์•Š์€ ํ˜•์‹์ด๋‹ค.
ํ•ญ๋ชฉ์ด ๋‹ค์†Œ ๋‚œ์žกํ•˜๊ณ  ๋‚ด์šฉ์˜ ๊ตฌ๋ถ„์ด ํ˜ผ๋™๋˜์–ด์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ๐Ÿคฃ

๐Ÿ—‚๏ธ useEffect vs useMemo vs useCallback vs useRef vs React.memo

  • ํ›…๋“ค์„ ๋‹ค์‹œ ๋ณต์Šตํ•˜๋Š”๋ฐโ€ฆ ์ด ๋…€์„๋“ค ์ •๋ง ๋ฌ˜ํ•˜๊ฒŒ ์•„์ฃผ ๋ฌ˜ํ•˜๊ฒŒ ๋‹ค๋ฅด๋‹ค.
  • ๊ฐ๊ฐ์˜ ๋ชฉ์  ๊ทธ๋ฆฌ๊ณ  ์ด๋ฆ„์— ๋‹ด๊ธด ์˜๋ฏธ, ํ™œ์šฉ์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ธฐ๋กํ•ด๋‘๋ ค ํ•œ๋‹ค.

useEffect

  • ์—ฌ๊ธฐ์„œ Effect๋ž€ Side Effect๋ฅผ ์˜๋ฏธํ•œ๋‹ค.
  • ๋ฆฌ์•กํŠธ๋Š” ๋ Œ๋”๋ง ๊ฒฐ๊ณผ๋ฌผ์„ ํ™”๋ฉด์— ๋ฐ˜์˜ํ•˜๋Š” ๊ฒƒ์ด ์ฃผ๋ชฉ์ ์ด๋‹ค.
  • ์ด ๋•Œ, ๋ Œ๋”๋ง๊ณผ ๋ฌด๊ด€ํ•œ ์ž‘์—…๋“ค์„ Side Effect๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • useEffect๋Š” ์ด๋Ÿฌํ•œ Side Effect๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค์–ด useEffect๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ fetch ์š”์ฒญ์„ ๋ณด๋‚ด๊ฑฐ๋‚˜, ๋กœ๊ทธ๋ฅผ ๋‚จ๊ธฐ๊ฑฐ๋‚˜, ํƒ€์ด๋จธ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
import { useEffect } from 'react';

function Example() {
  // ...
  useEffect(() => {
    fetch('https://api.example.com/items')
      .then((res) => res.json())
      .then((data) => {});
    return () => {
      // cleanup
    };
  }, [x]);
  return <div></div>;
}

์œ„์˜ ์˜ˆ์‹œ ์ฝ”๋“œ์—์„œ useEffect ๋‚ด์˜ ํ•จ์ˆ˜๋Š” fetch ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ , cleanup ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ด ๋•Œ, x๊ฐ€ ์—†์ด ๋นˆ ๋ฐฐ์—ด์ด๋ผ๋ฉด ์ฒซ mount ๋•Œ fetch ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๊ณ  unmount ๋•Œ cleanup ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค. x๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ, ์ฒซ ๋งˆ์šดํŠธ ๋•Œ ๊ทธ๋ฆฌ๊ณ  x๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค fetch ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๊ณ , x๊ฐ€ ๋ณ€๊ฒฝ๋˜๊ธฐ ์ง์ „์— ๊ทธ๋ฆฌ๊ณ  unmount ๋•Œ cleanup ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค.

์ฆ‰, useEffect๋Š” ๋ Œ๋”๋ง๊ณผ ๋ฌด๊ด€ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” hook์ด๋‹ค.

useMemo

  • Memo๋ž€ Memory์˜ ์•ฝ์ž๋กœ, ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ์ฆ‰, ์ž ์‹œ ๊ธฐ์–ตํ•ด๋‘๊ธฐ ์œ„ํ•œ ์šฉ๋„๋กœ ์‚ฌ์šฉ๋œ๋‹ค.
  • useMemo๋Š” ์ „๋‹ฌ๋˜๋Š” ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜๊ฐ’์„ ๊ธฐ์–ตํ•œ๋‹ค.
const memoValue = useMemo(() => {
  return 'memo value!';
}, [x]);
  • x์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๊ธฐ ์ „๊นŒ์ง€๋Š” โ€˜memo value!โ€™๋ฅผ ๊ธฐ์–ตํ•˜๊ณ  ์žˆ๋‹ค๊ฐ€, x์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด ๋‹ค์‹œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ๋ฐ˜ํ™˜๊ฐ’์„ ๊ธฐ์–ตํ•œ๋‹ค.
  • ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ๋œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜์–ด ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ’์„ ๊ธฐ์–ตํ•œ๋‹ค.

useCallback

  • Callback์ด๋ž€ ํ•จ์ˆ˜๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ์ฆ‰, ํ•จ์ˆ˜๋ฅผ ๊ธฐ์–ตํ•˜๊ธฐ ์œ„ํ•œ ์šฉ๋„๋กœ ์‚ฌ์šฉ๋œ๋‹ค.
const callback = useCallback(() => {
  return 'callback function!';
}, [x]);
  • x์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๊ธฐ ์ „๊นŒ์ง€๋Š” ์ „๋‹ฌ๋œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ์ž์ฒด๋ฅผ ๊ธฐ์–ตํ•˜๊ณ  ์žˆ๋‹ค๊ฐ€, x์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด ๋‹ค์‹œ ๊ทธ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๊ธฐ์–ตํ•œ๋‹ค.
const memoCallback = useMemo(
  () => () => {
    return 'callback function!';
  },
  [x],
);
  • useMemo๋ฅผ ํ†ตํ•ด ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๊ธฐ์–ตํ•˜๊ณ , ๊ทธ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ useCallback์„ ํ†ตํ•ด ๊ธฐ์–ตํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•˜๋‹ค.

useRef

  • Ref๋ž€ ์ฐธ์กฐ๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ์ฆ‰, ์ฐธ์กฐ๋ฅผ ์œ„ํ•œ ์šฉ๋„๋กœ ์‚ฌ์šฉ๋œ๋‹ค.
  • useRef๋Š” ์ „๋‹ฌ๋˜๋Š” ๊ฐ’์˜ ์ฐธ์กฐ๋ฅผ ๊ธฐ์–ตํ•œ๋‹ค.
const ref = useRef('ref value!');

// ref.current === 'ref value!'
  • ref.current๋Š” ์ „๋‹ฌ๋œ ๊ฐ’์˜ ์ฐธ์กฐ๋ฅผ ๊ธฐ์–ตํ•œ๋‹ค.
  • ref.current๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š”๋‹ค.(๋””ํŽœ๋˜์‹œ๊ฐ€ ์—†๋‹ค.)
  • ์ฃผ๋กœ DOM์„ ์ฐธ์กฐํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.

React.memo

  • ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋กœ ์ž‘์„ฑํ–ˆ์„ ๋•Œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ์ž์ฒด์˜ ๋ Œ๋”๋ง ๊ฒฐ๊ณผ๋ฌผ์„ ๊ธฐ์–ตํ•œ๋‹ค.
  • ๋ณ€์ˆ˜๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ํ•œ, ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋Š” ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜์ง€ ์•Š๋Š”๋‹ค.
const MemoComponent = React.memo(({ value, handleFunction }) => {
  return <div>MemoComponent</div>;
});
  • value์™€ handleFunction์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ํ•œ, MemoComponent๋Š” ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜์ง€ ์•Š๋Š”๋‹ค.
  • value๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์ง€๋งŒ, handleFunction์€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, handleFunction์€ useCallback์„ ํ†ตํ•ด ๊ธฐ์–ตํ•ด๋‘๋„๋ก ํ•œ๋‹ค.

์ฐธ๊ณ