4. useRef & Custom hook

keyword

  • useRef

  • Hook์˜ ๊ทœ์น™

1. useRef

useRef๋Š” ๋ Œ๋”๋ง์— ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ฐ’์„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋Š” React Hook์œผ๋กœ ๊ฐ’(current)์ด ๋ฐ”๋€Œ์–ด๋„ ๋ฆฌ๋ Œ๋”๋ง์„ ํŠธ๋ฆฌ๊ฑฐํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์–ธ๋งˆ์šดํŠธ๋  ๋•Œ๊นŒ์ง€ ๋™์ผํ•œ ๊ฐ์ฒด๊ฐ€ ์œ ์ง€๋œ๋‹ค. ref๋Š” ์ผ๋ฐ˜ JS๊ฐ์ฒด(์ฐธ์กฐํ˜• ๋ฐ์ดํ„ฐ)์ด๊ธฐ ๋•Œ๋ฌธ์— React๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์–ธ์ œ ๋ณ€๊ฒฝํ–ˆ๋Š”์ง€ ์•Œ์ง€ ๋ชปํ•œ๋‹ค.

์ฃผ์š” ์šฉ๋„

  1. ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์–ธ๋งˆ์šดํŠธ๋  ๋•Œ๊นŒ์ง€ ๋™์ผํ•œ ๊ฐ’์„ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๊ฒฝ์šฐ

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

1๋ฒˆ ์˜ˆ์‹œ ์ฝ”๋“œ

// ์™ธ๋ถ€์—์„œ ref ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•  ๊ฒฝ์šฐ
const ref = {
  value: 1,
}

function TimerControl() {
  ref.value += 1;
}

// useRef๋ฅผ ํ˜ธ์ถœํ•ด ๊ฐ’์„ ์ฐธ์กฐํ•  ๊ฒฝ์šฐ
function TimerControl() {
  const ref = useRef(1);
  ref.current += 1;
}

TimerControl ์ปดํฌ๋„ŒํŠธ๋ฅผ 10๋ฒˆ ์žฌ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ์„ ๋•Œ, ๊ฐ ์ปดํฌ๋„ŒํŠธ๋Š” ๋™์ผํ•œ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฐธ์กฐํ•˜๋ฏ€๋กœ value์˜ ๊ฐ’์ด +10 ์ฆ๊ฐ€ํ•  ๊ฒƒ์ด๋‹ค. ๋•Œ๋ฌธ์— useRef hook์„ ํ˜ธ์ถœํ•ด ๊ฐ์ž์˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋…๋ฆฝ์ ์ธ ๊ฐ’์„ ๊ฐ–๊ฒŒ๋œ๋‹ค.

2๋ฒˆ ์˜ˆ์‹œ ์ฝ”๋“œ

import { useState, useRef } from 'react';

const query = useRef('');
const [filterText, setFilterText] = useState('');

// filterText๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ ๋งˆ๋‹ค query.current์— ๊ฐ’์ด ํ• ๋‹น๋จ
useEffect(() => {
  query.current = filterText;
}, [filterText]);

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

ํด๋กœ์ €๋กœ ์ธํ•œ ๋ณ€์ˆ˜๋ฅผ ์บก์ฒ˜, ๋ฐ”์ธ๋“œ๋ฅผ ๊นœ๋นกํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์ผ์–ด๋‚œ๋‹ค๋Š” ๋ง์— ์ฒจ์–ธํ•˜์ž๋ฉด, ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋Š” ๊ฒฐ๊ตญ ํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— ์ƒ๋ช…์ฃผ๊ธฐ๊ฐ€ ๋๋‚˜๋ฉด ์ง€์—ญ๋ณ€์ˆ˜๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ๋˜๋Š”๋ฐ ์ด ํด๋กœ์ € ํŒจํ„ด์„ ์ด์šฉํ•  ์‹œ ํ•จ์ˆ˜์˜ ์ƒ๋ช…์ฃผ๊ธฐ๊ฐ€ ๋๋‚ฌ์Œ์—๋„ ๋‚ด๋ถ€ ํ•จ์ˆ˜์—์„œ ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณ€์ˆ˜์˜ ์บก์ณ, ๋ฐ”์ธ๋“œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. useState๋„ ๋‚ด๋ถ€์ ์œผ๋กœ ํด๋กœ์ €๋ฅผ ์ด์šฉํ•ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฐ˜ํ™˜๋œ ํ›„์—๋„ ๊ณ„์† ์ƒํƒœ๊ฐ’์„ ์ฐธ์กฐํ•˜๋ฉฐ ํ™”๋ฉด์— ๋ณด์—ฌ์ฃผ๊ณ  ๊ทธ ์ƒํƒœ๋ฅผ ๊ฐ€์ง€๊ณ  1์”ฉ ๋”ํ•˜๊ฑฐ๋‚˜ ํ•˜๋Š”๋“ฑ์˜ ๊ณ„์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ ์—…๋ฐ์ดํŠธ ํ•˜๋Š” ๊ฒƒ์ธ๋ฐ, ์ด๋Ÿฌํ•œ ์›๋ฆฌ๋กœ ์ธํ•˜์—ฌ ํ˜„์žฌ useEffect๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ ์‹œ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋˜๋ฏ€๋กœ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋กœ ์ธํ•œ ์ปดํฌ๋„ŒํŠธ ๋ฆฌ๋ Œ๋”๋ง์ด ๋ฐœ์ƒํ•˜๊ธฐ ์ „๊นŒ์ง„ ๋‹น์‹œ์˜ ์ƒํƒœ๊ฐ’์„ ์ฐธ์กฐํ•˜์—ฌ 5์ดˆ ๋’ค์— ๋นˆ ๋ฌธ์ž์—ด์ด ์ถœ๋ ฅ๋œ๋‹ค.


2. Hook์˜ ๊ทœ์น™

React Hooks์˜ ํ˜ธ์ถœ์€ ์ปดํฌ๋„ŒํŠธ ๋˜๋Š” Custom Hook์˜ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ์—์„œ ํ˜ธ์ถœํ•ด์•ผํ•œ๋‹ค. ์ข…์ข… ์กฐ๊ฑด๋ฌธ์ด๋‚˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ํ˜ธ์ถœํ•˜๋Š” ์‹ค์ˆ˜๋ฅผ ๋ฒ”ํ•œ๋‹ค.

์ž˜๋ชป๋œ ์˜ˆ์ œ ์ฝ”๋“œ

const [playing, setPlaying] = useState(false);

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

์ถ”๊ฐ€ ํ‚ค์›Œ๋“œ

  • Custom hook

Custom hook

๋กœ์ง์„ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ• React์˜ ํ›…์„ ์‚ฌ์šฉํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ ๋กœ์ง์„ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜์ด๋‹ค. ์ปค์Šคํ…€ ํ›…์— ๋ถ€์ˆ˜ ํšจ๊ณผ ์ž‘์—…์ด๋‚˜ ์ƒํƒœ ๊ด€๋ฆฌ ๋กœ์ง์„ ์บก์Аํ™”ํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋‹ค ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ์ปค์Šคํ…€ ํ›…์˜ ์ด๋ฆ„์€ use ๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•œ๋‹ค.

์˜ˆ์‹œ ์ฝ”๋“œ

// ์„œ๋ฒ„ ์š”์ฒญ ์ปค์Šคํ…€ ํ›…
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;
}

๋‚ด๋ถ€์—์„œ API ์š”์ฒญ์„ ๋ณด๋‚ด๊ฑฐ๋‚˜, useEffect๋ฅผ ์“ฐ๊ฑฐ๋‚˜ ์ปค์Šคํ…€ ํ›…์„ ํ˜ธ์ถœํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋Š” ๋‚ด๋ถ€ ๋กœ์ง์— ๋Œ€ํ•ด ๊ด€์‹ฌ์ด ์—†๊ณ  ๊ทธ์ € ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ’๋งŒ ๊ฐ€์ ธ๋‹ค ์“ด๋‹ค.

Last updated