๐Ÿ’ป์›น(Web)/React

React hook: useEffect, useState, useMemo, useCallback

stonesy 2024. 11. 10. 11:25
728x90

useEffect

์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง๋  ๋•Œ ํŠน์ • ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ฑฐ๋‚˜, ์ƒํƒœ๊ฐ€ props๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ํŠน์ • ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

 

useState

state์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋œ๋‹ค.

 

  • useState: ์ƒํƒœ๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋œ๋‹ค. ๋ Œ๋”๋ง์— ๋ฐ˜์˜๋˜์–ด UI์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉํ•œ.
  • useRef: ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋”๋ผ๋„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜์ง€ ์•Š๋Š”๋‹ค. ์ฆ‰, useRef๋Š” ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋”๋ผ๋„ ํ™”๋ฉด์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š” ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

๋”ฐ๋ผ์„œ ์ž…๋ ฅ ๊ฐ’์ด ํ™”๋ฉด์— ์ฆ‰์‹œ ๋ฐ˜์˜๋˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ•ด๋‹น ์ƒํƒœ๋ฅผ ์ฐธ๊ณ ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด useRef๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฆฌ๋ Œ๋”๋ง์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

useMemo

useMemo๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ state๊ฐ€ ์žˆ์„ ๋•Œ ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง์„ ๋ฐฉ์ง€ํ•˜๋Š”๋ฐ ๋„์›€์ด ๋œ๋‹ค. ํŠนํžˆ, ์–ด๋–ค ๊ฐ’์ด๋‚˜ ์—ฐ์‚ฐ์ด ํŠน์ • ์ƒํƒœ์˜ ๋ณ€๊ฒฝ์— ์˜ํ•ด์„œ๋งŒ ๋‹ค์‹œ ๊ณ„์‚ฐ๋˜๊ธฐ๋ฅผ ์›ํ•  ๋•Œ useMemo๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ์—์„œ useMemo๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด otherCount ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋•Œ๋„ ๋ถˆํ•„์š”ํ•˜๊ฒŒ fibonacci ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋‹ค.

import React, { useState, useMemo } from 'react';

function ExpensiveComponent() {
  const [count, setCount] = useState(0);
  const [otherCount, setOtherCount] = useState(0);

  // ๋ณต์žกํ•œ ๊ณ„์‚ฐ ์˜ˆ์‹œ: ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด ๊ณ„์‚ฐ
  const calculateFibonacci = (num) => {
    console.log("Calculating Fibonacci...");
    if (num <= 1) return num;
    return calculateFibonacci(num - 1) + calculateFibonacci(num - 2);
  };

  // `count`๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งŒ Fibonacci ๊ณ„์‚ฐ ์‹คํ–‰
  const fibonacci = useMemo(() => calculateFibonacci(count), [count]);

  return (
    <div>
      <h1>useMemo Example - Expensive Calculation</h1>
      <p>Count: {count}</p>
      <p>Fibonacci of Count: {fibonacci}</p>
      <button onClick={() => setCount(count + 1)}>Increase Count</button>

      <p>Other Count: {otherCount}</p>
      <button onClick={() => setOtherCount(otherCount + 1)}>Increase Other Count</button>
    </div>
  );
}

export default ExpensiveComponent;

 

 

useCallback

useMemo๋Š” ๊ฐ’์„ memoizationํ•œ๋‹ค๋ฉด, useCallback์€ ํ•จ์ˆ˜ ์ž์ฒด๋ฅผ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•œ๋‹ค.

์•„๋ž˜์˜ ์ฝ”๋“œ๋Š” useMemo์˜ ์˜ˆ์‹œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ count๊ฐ€ ๋ณ€ํ•  ๋•Œ๋งŒ ๋ฆฌ๋ Œ๋”๋ง ๋˜๋„๋ก ๋ฉ”๋ชจ์ด์ œ์ด์…˜ํ•œ ๊ฒƒ์ด๋‹ค.

import React, { useState, useCallback } from 'react';
import ChildComponent from './ChildComponent';

function ParentComponent() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');

  // `handleClick` ํ•จ์ˆ˜๊ฐ€ `count`๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งŒ ์ƒˆ๋กœ ์ƒ์„ฑ๋จ
  const handleClick = useCallback(() => {
    setCount(count + 1);
  }, [count]);

  return (
    <div>
      <h1>useCallback Example</h1>
      <p>Count: {count}</p>
      <button onClick={handleClick}>Increase Count</button>

      <input
        type="text"
        value={text}
        onChange={(e) => setText(e.target.value)}
        placeholder="Type something..."
      />

      {/* ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ์ฝœ๋ฐฑ ์ „๋‹ฌ */}
      <ChildComponent onClick={handleClick} />
    </div>
  );
}

export default ParentComponent;

 

ํ•˜์ง€๋งŒ useMemo์™€ useCallback ๋ชจ๋‘ ๊ณ„์‚ฐ ๋น„์šฉ ์ž์ฒด๊ฐ€ ๋“ค๊ธฐ ๋•Œ๋ฌธ์— ๋ณต์žกํ•œ ์—ฐ์‚ฐ์„ ํฌํ•จํ–ˆ์„ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ ์ ˆํ•˜๋‹ค. ์ˆ˜์ฒœ ๊ฐœ ์ด์ƒ์˜ ํ•ญ๋ชฉ์„ ํ•„ํ„ฐ๋งํ•˜๊ฑฐ๋‚˜ ์žฌ๊ท€์  ์—ฐ์‚ฐ์ด ํ•„์š”ํ•˜๊ฑฐ๋‚˜ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ณ ๋น„์šฉ ์—ฐ์‚ฐ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋“ฑ๋“ฑ..

728x90