4. useRef & Custom Hook

  • useRef

  • Hook์˜ ๊ทœ์น™

๊ฐ•์˜ ์ •๋ฆฌ

useRef

useRef๋Š” ๊ฐ’์„ ์ฐธ์กฐํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ์ฒด์ด๋‹ค. ์ƒํƒœ๋ž‘ ์ƒ๊ด€์—†์ด ๊ฐ’์„ ๊ณ„์† ์œ ์ง€ํ•˜๊ณ  ์‹ถ์„ ๋•Œ useRef๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด Component์—์„œ ๊ทธ๋ƒฅ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋˜์ง€ ์•Š์„๊นŒ? ๋ผ๋Š” ์˜๋ฌธ์ด ๋“ค ๊ฒƒ ๊ฐ™๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•˜๊ฒŒ ๋˜๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง์ด ๋  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กญ๊ฒŒ ref ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ ๋‹ค.

export default function Component {
  const ref = {
    value: 1
  }
  ref.value = 2
}

๊ทธ๋ ‡๋‹ค๋ฉด ์ปดํฌ๋„ŒํŠธ ์™ธ๋ถ€์— ์ž‘์„ฑํ•˜๋ฉด ์–ด๋–จ๊นŒ? ์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•  ๊ฒฝ์šฐ์˜ ๋ฌธ์ œ์ ์€ Component๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ ๋ Œ๋”๋ง์ด ๋˜๋ฉด ์—ฌ๋Ÿฌ Component๊ฐ€ ๋™์ผํ•œ ref๋ฅผ ์ฐธ์กฐํ•˜๊ฒŒ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์ปดํฌ๋„ŒํŠธ ๊ฐœ์ธ์˜ ref๋ฅผ ๊ฐ€์งˆ์ˆ˜๊ฐ€ ์—†๋‹ค.

const ref = {
  value: 1
}
export default function Component {
  ref.value = 2
}

์ด๋ฅผ ์œ„ํ•ด์„œ Component์—์„œ๋Š” ref๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.

import { useRef } from 'react';

export default function Component {
  const ref = useRef(1);
  ref.current += 1;
}

ref๋Š” state์™€ ๋‹ค๋ฅด๊ฒŒ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์–ด๋„ ๋ฆฌ๋ Œ๋”๋ง์˜ trigger๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค. ์ฃผ์š” ์šฉ๋„:

  1. ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ๋ผ์งˆ ๋•Œ๊นŒ์ง€ ๋™์ผํ•œ ๊ฐ’์„ ์จ์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ -> input๋“ฑ์˜ id ๊ด€๋ฆฌ

  2. (ํŠนํžˆ useEffect ๋“ฑ๊ณผ ํ•จ๊ป˜ ์“ฐ๋ฉด์„œ ๋งŒ๋‚˜๊ฒŒ ๋˜๋Š”) ๋น„๋™๊ธฐ ์ƒํ™ฉ์—์„œ ํ˜„์žฌ ๊ฐ’์„ ์ œ๋Œ€๋กœ ์“ฐ๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ.

useEffect๋Š” ์ฒ˜์Œ ๋ Œ๋”๋ง๋˜์„œ setup function์ด ์‹คํ–‰ ๋˜์—ˆ์„ ๋–„์˜ ํ™˜๊ฒฝ์„ ๊ธฐ์–ตํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ๋ Œ๋”๋ง ์ดํ›„์— state๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด๋„ ๋ณ€๊ฒฝ๋œ ๊ฐ’์„ ์ฐธ์กฐํ•˜์ง€ ์•Š๋Š”๋‹ค.

useEffect(() => {
  setTimeout(() => {
    console.log(filterText);
  }, 5_000);
}, []);

Custom Hook

Component ๋‚ด๋ถ€์˜ ๋„๋ฉ”์ธ ๋กœ์ง์„ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์ œ์ผ ์‰ฌ์šด ๋ฐฉ๋ฒ• ์ปดํฌ๋„ŒํŠธ์—์„œ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋ฅผ ๊ทธ๋Œ€๋กœ ๊ฐ€์ ธ๊ฐ€์„œ use prefix๋ฅผ ๋ถ™์ธ ํŒŒ์ผ๋กœ ์ถ”์ถœํ•˜๋ฉด ๋œ๋‹ค.

function useFetchProducts() {
  const [products, setProducts] = useState<Product[]>([]);

  useEffect(() => {
    const fetchProducts = async () => {
      const url = 'http://localhost:3000/products';
      const response = await fetch(url);
      const data = await response.json();
      setProducts(data.products);
    };

    fetchProducts();
  }, []);

  return products;
}

Custom Hook์€ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋„๋ฉ”์ธ ๋กœ์ง์„ ๋ถ„๋ฆฌํ•œ๋‹ค. ๊ณต์‹๋ฌธ์„œ์—๋Š” ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋กœ์ง์˜ ๊ฒฝ์šฐ ์ œ์‚ฌ์šฉ์„ ์œ„ํ•ด ๋ถ„๋ฆฌํ•œ๋‹ค๊ณ  ๋‚˜์™€์žˆ๋Š”๋ฐ ๊ผญ ์—ฌ๋Ÿฌ๊ณณ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ์–ด๋„ ๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ๋ฅผ ์œ„ํ•ด Custom Hook์œผ๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒŒ ์ข‹์€ ๊ฒƒ ๊ฐ™๋‹ค. ์‹ค์ œ ๋‚ด๋ถ€ ๊ตฌํ˜„์€ ์–ด๋–ป๊ฒŒ ๋˜์–ด์žˆ๋Š”์ง€ ์‚ฌ์šฉํ•˜๋Š” Component์—์„  ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š๋Š”๋‹ค.

Hook ๊ทœ์น™

Hook์€ Component์˜ ์ตœ์ƒ์œ„์—์„œ๋งŒ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.

if (playing) {
  const products = useFetchProducts();
  console.log(products);
}

๋งŒ์•ฝ ํŠน์ • ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ data fetching์„ ํ•˜๋ ค๊ณ  ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” Custom Hook ์ž์ฒด๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, Custom Hook ๋‚ด๋ถ€์˜ data fetching ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

Last updated