๊ด€๋ฆฌ ๋ฉ”๋‰ด

Daily Front_Minhhk

Hooks & useMemo, useCallback ๋ณธ๋ฌธ

Code๊ฐœ๋ฐœ์ผ์ง€

Hooks & useMemo, useCallback

Minhhk 2023. 1. 25. 15:28

๐Ÿ‘€ Hook

 

ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ state ๊ฐ’ ๋ฐ ๋‹ค๋ฅธ ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ํŽธํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ๋ฉ”์†Œ๋“œ๋กœ, function์œผ๋กœ๋งŒ React๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— Class Component์—์„œ๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค.



โœ” Hook ์‚ฌ์šฉ ๊ทœ์น™

 

1. React ํ•จ์ˆ˜์˜ ์ตœ์ƒ์œ„์—์„œ๋งŒ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.

๋ฐ˜๋ณต๋ฌธ, ์กฐ๊ฑด๋ฌธ, ์ค‘์ฒฉ๋œ ํ•จ์ˆ˜ ๋‚ด์—์„œ ์‹คํ–‰ ์‹œ, ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค.

2. React ํ•จ์ˆ˜ ๋‚ด์—์„œ๋งŒ ์‚ฌ์šฉ๋˜์–ด์•ผ ํ•œ๋‹ค.

๋ฆฌ์•กํŠธ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋‚˜ ์ปค์Šคํ…€ Hook์ด ์•„๋‹Œ ๋‹ค๋ฅธ ์ผ๋ฐ˜ JavaScript ํ•จ์ˆ˜ ์•ˆ์—์„œ ํ˜ธ์ถœํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

 

 


useMemo๋ž€?

useMemo๋Š” ํŠน์ • ๊ฐ’(value)๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” Hook์ž…๋‹ˆ๋‹ค.

import { useMemo } from "react";

function Calculator({value}){

	const result = useMemo(() => calculate(value), [value]);

	return 
  <>
      <div>
      {result}
      </div>
  </>;
}

์—ฌ๊ธฐ value ๋ฅผ ์ธ์ž๋กœ ๋ฐ›๋Š” Calculator ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. value ๋Š” ์ผ์ข…์˜ ๊ฐ’์œผ๋กœ์„œ, ์ด ๊ฐ’์ด ๊ณ„์† ๋ฐ”๋€Œ๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด ์–ด์ฉ” ์ˆ˜ ์—†๊ฒ ์ง€๋งŒ, ๋ Œ๋”๋ง์„ ํ•  ๋•Œ๋งˆ๋‹ค ์ด value๊ฐ’์ด ๊ณ„์† ๋ฐ”๋€Œ๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•ด ๋ด…์‹œ๋‹ค. ๊ทธ๋Ÿผ ์ด ๊ฐ’์„ ์–ด๋”˜๊ฐ€์— ์ €์žฅ์„ ํ•ด๋’€๋‹ค๊ฐ€ ๋‹ค์‹œ ๊บผ๋‚ด์„œ ์“ธ ์ˆ˜๋งŒ ์žˆ๋‹ค๋ฉด ๊ตณ์ด calculate ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ํ•„์š”๋„ ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ useMemo Hook์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

 

์ด๋Š” ๋ฉ”๋ชจ์ด์ œ์ด์…˜(Memoization) ๊ฐœ๋…๊ณผ ๊ธด๋ฐ€ํ•œ ๊ด€๊ณ„๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

โญ ๋ฉ”๋ชจ์ด์ œ์ด์…˜(Memoization)?
๊ธฐ์กด์— ์ˆ˜ํ–‰ํ•œ ์—ฐ์‚ฐ์˜ ๊ฒฐ๊ณผ๊ฐ’์„ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•ด๋‘๊ณ , ๋™์ผํ•œ ์ž…๋ ฅ์ด ๋“ค์–ด์˜ค๋ฉด ์žฌํ™œ์šฉํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ๋ฒ•์ด๋‹ค.

useMemo๋Š” ๋ฐ”๋กœ ์ด ๊ฐœ๋…์„ ์ด์šฉํ•˜์—ฌ ๋ณต์žกํ•œ ์—ฐ์‚ฐ์˜ ์ค‘๋ณต์„ ํ”ผํ•˜๊ณ  React ์•ฑ์˜ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”์‹œํ‚จ๋‹ค.

 

 

์‹ค์Šต

useMemo()

useMemo๋Š” ๊ฐ’์˜ ์žฌ์‚ฌ์šฉ์„ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” Hook

import React, { useMemo, useState } from "react";
import "./styles.css";
import { add } from "./add";

export default function App() {
  const [name, setName] = useState("");
  const [val1, setVal1] = useState(0);
  const [val2, setVal2] = useState(0);
  // const answer = add(val1, val2);

  const answer = useMemo(()=> {add(val1, val2)}, [val1, val2])
  return (
    <div>
      <input
        className="name-input"
        placeholder="์ด๋ฆ„์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"
        value={name}
        type="text"
        onChange={(e) => setName(e.target.value)}
      />
      <input
        className="value-input"
        placeholder="์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"
        value={val1}
        type="number"
        onChange={(e) => setVal1(Number(e.target.value))}
      />
      <input
        className="value-input"
        placeholder="์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"
        value={val2}
        type="number"
        onChange={(e) => setVal2(Number(e.target.value))}
      />
      <div>{answer}</div>
    </div>
  );
}

์ด๋ฆ„ (์ฒซ๋ฒˆ์งธ)์ธํ’‹์— ์ž…๋ ฅ์‹œ ๋žœ๋”๋ง ๋˜์ง€ ์•Š๊ณ ,

์ˆซ์ž ๊ฐ’ (๋‘๋ฒˆ์งธ, ์„ธ๋ฒˆ์งธ) ์“ฐ๋Š” ์ธํ’‹์— ์ž…๋ ฅ์‹œ ์žฌ๋žœ๋”๋ง!

 

 


 

useCallback์ด๋ž€?

useCallback ๋˜ํ•œ useMemo์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๊ธฐ๋ฒ•์„ ์ด์šฉํ•œ Hook์ด๋‹ค.

useCallback์€ ํ•จ์ˆ˜์˜ ์žฌ์‚ฌ์šฉ์„ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” Hook์ด๋‹ค.

 

 

import React, { useCallback } from "react";

function Calculator({x, y}){

	const add = useCallback(() => x + y, [x, y]);

	return <>
      <div>
		{add()}
      </div>
  </>;
}

useMemo์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋˜๋”๋ผ๋„ ๊ทธ ํ•จ์ˆ˜๊ฐ€ ์˜์กดํ•˜๊ณ  ์žˆ๋Š” ๊ฐ’์ธ x์™€ y๊ฐ€ ๋ฐ”๋€Œ์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ด ๋ด…์‹œ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ํ•จ์ˆ˜ ๋˜ํ•œ ๋ฉ”๋ชจ๋ฆฌ ์–ด๋”˜๊ฐ€์— ์ €์žฅํ•ด ๋’€๋‹ค๊ฐ€ ๋‹ค์‹œ ๊บผ๋‚ด์„œ ์“ธ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๋•Œ useCallback Hook์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ทธ ํ•จ์ˆ˜๊ฐ€ ์˜์กดํ•˜๋Š” ๊ฐ’๋“ค์ด ๋ฐ”๋€Œ์ง€ ์•Š๋Š” ํ•œ ๊ธฐ์กด ํ•จ์ˆ˜๋ฅผ ๊ณ„์†ํ•ด์„œ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์ฆ‰ x์™€ y๊ฐ’์ด ๋™์ผํ•˜๋‹ค๋ฉด ๋‹ค์Œ ๋ Œ๋”๋ง ๋•Œ ์ด ํ•จ์ˆ˜๋ฅผ ๋‹ค์‹œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

 

useCallback์€ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ์„ ํ•˜์ง€ ์•Š๋Š” Hook์ด ์•„๋‹ˆ๋ผ, ๊ทธ์ € ๋ฉ”๋ชจ๋ฆฌ ์–ด๋”˜๊ฐ€์— ํ•จ์ˆ˜๋ฅผ ๊บผ๋‚ด์„œ ํ˜ธ์ถœํ•˜๋Š” Hook์ด๊ธฐ ๋•Œ๋ฌธ์—

๋‹จ์ˆœํžˆ ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด์„œ

useCallback์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ํฐ ์˜๋ฏธ๊ฐ€ ์—†๊ฑฐ๋‚˜ ์˜คํžˆ๋ ค ์†ํ•ด์ธ ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค.

 

์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ props๋กœ ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•ด์ค„ ๋•Œ ์ด useCallback์„ ์‚ฌ์šฉํ•˜๊ธฐ๊ฐ€ ์ข‹์Šต๋‹ˆ๋‹ค.

 

 

useCallback๊ณผ ์ฐธ์กฐ ๋™๋“ฑ์„ฑ

useCallback์€ ์ฐธ์กฐ ๋™๋“ฑ์„ฑ์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค. React๋Š” JavaScript ์–ธ์–ด๋กœ ๋งŒ๋“ค์–ด์ง„ ์˜คํ”ˆ์†Œ์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ์ ์œผ๋กœ JavaScript์˜ ๋ฌธ๋ฒ•์„ ๋”ฐ๋ผ๊ฐ‘๋‹ˆ๋‹ค.

JavaScript์—์„œ ํ•จ์ˆ˜๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.

๊ฐ์ฒด๋Š” ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•  ๋•Œ ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ๊ฐ’์˜ ์ฃผ์†Œ๋ฅผ ์ €์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ’์ด ๊ฐ™์„ ์ง€๋ผ๋„ ์ผ์น˜์—ฐ์‚ฐ์ž๋กœ ๋น„๊ตํ–ˆ์„ ๋•Œ false๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

 

->

 

React ๋˜ํ•œ ๊ฐ™์Šต๋‹ˆ๋‹ค. React๋Š” ๋ฆฌ๋ Œ๋”๋ง ์‹œ ํ•จ์ˆ˜๋ฅผ ์ƒˆ๋กœ์ด ๋งŒ๋“ค์–ด์„œ ํ˜ธ์ถœ์„ ํ•ฉ๋‹ˆ๋‹ค.

์ƒˆ๋กœ์ด ๋งŒ๋“ค์–ด ํ˜ธ์ถœ๋œ ํ•จ์ˆ˜๋Š” ๊ธฐ์กด์˜ ํ•จ์ˆ˜์™€ ๊ฐ™์€ ํ•จ์ˆ˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ useCallback์„ ์ด์šฉํ•ด ํ•จ์ˆ˜ ์ž์ฒด๋ฅผ ์ €์žฅํ•ด์„œ ๋‹ค์‹œ ์‚ฌ์šฉํ•˜๋ฉด ํ•จ์ˆ˜์˜ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ ๊ฐ’์„ ์ €์žฅํ–ˆ๋‹ค๊ฐ€ ๋‹ค์‹œ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ๊ณผ ๊ฐ™๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ React ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜ ๋‚ด์—์„œ ๋‹ค๋ฅธ ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ๋„˜๊ธฐ๊ฑฐ๋‚˜ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ prop์œผ๋กœ ๋„˜๊ธธ ๋•Œ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๐Ÿค์‹ค์Šต

useCallback()

import { useState, useCallback } from "react";
import "./styles.css";
import List from "./List";

export default function App() {
  const [input, setInput] = useState(1);
  const [light, setLight] = useState(true);

  const theme = {
    backgroundColor: light ? "White" : "grey",
    color: light ? "grey" : "white"
  };

  const getItems = useCallback(() => {
    return [input + 10, input + 100];
  }, [input]);

  const handleChange = (event) => {
    if (Number(event.target.value)) {
      setInput(Number(event.target.value));
    }
  };

  return (
    <>
      <div style={theme} className="wall-paper">
        <input
          type="number"
          className="input"
          value={input}
          onChange={handleChange}
        />
        <button
          className={(light ? "light" : "dark") + " button"}
          onClick={() => setLight((prevLight) => !prevLight)}
        >
          {light ? "dark mode" : "light mode"}
        </button>
        <List getItems={getItems} />
      </div>
    </>
  );
}

'Code๊ฐœ๋ฐœ์ผ์ง€' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

React.lazy()์™€ Suspense  (0) 2023.01.26
Custom Hooks  (0) 2023.01.25
๋ฒˆ๋“ค๋ง๊ณผ ์›นํŒฉ  (0) 2023.01.18
๋ฐ˜์‘ํ˜• ์›น  (0) 2023.01.16
๋ธŒ๋ผ์šฐ์ €  (0) 2023.01.16