useCallback()

useCallback()

1. κ°œμš”

useCallback()훅은 useMemo()와 λ”λΆˆμ–΄ μ„±λŠ₯ μ΅œμ ν™”μ— μ‚¬μš©λ˜λŠ” React의 훅이닀. useMemo()λŠ” νŠΉμ • 결과값을 μž¬μ‚¬μš©ν•  λ•Œ μ‚¬μš©ν•˜λŠ” 반면, useCallback()훅은 νŠΉμ • ν•¨μˆ˜λ₯Ό μƒˆλ‘œ λ§Œλ“€μ§€ μ•Šκ³  μž¬μ‚¬μš©ν•˜κ³  싢을 λ•Œ μ‚¬μš©ν•˜λŠ” 훅이닀.


2. useCallback() μ‚¬μš©λ²•

μ‚¬μš©λ²• const fn = useCallback(function, deps)

  • function: Memoization을 ν•˜λŠ” ν•¨μˆ˜

  • deps: μ˜μ‘΄μ„± λ°°μ—΄λ‘œ useEffect()의 deps와 κ°™λ‹€.

κΈ°λ³Έ μ‚¬μš©λ²•μ€ useMemo()κ³Ό κ°™μ•„ 보인닀. ν•˜μ§€λ§Œ ν•¨μˆ˜λ₯Ό Memoizationν•˜λŠ”μ§€ νŠΉμ • 값을 Memoization이 ν•˜λŠ” 것에 차이가 μžˆλ‹€.


3. useCallback()λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” μ»΄ν¬λ„ŒνŠΈμ˜ λžœλ”λ§

λ¨Όμ € useCallback()훅을 μ‚¬μš©ν•˜μ§€ μ•Šμ€ μ½”λ“œλ₯Ό μž‘μ„±ν•˜κ³  λžœλ”λ§ν•˜λŠ” 과정을 μ‚΄νŽ΄λ³΄μž. μ΅œκ·Όμ— μ œμ£Όλ„ 여행을 닀녀왔기에 이와 κ΄€λ ¨ν•œ κ°„λ‹¨ν•œ μ½”λ“œλ₯Ό μ˜ˆμ‹œλ‘œ μ†Œκ°œν•œλ‹€.

μ•„λž˜μ™€ 같이 두 개의 μ»΄ν¬λ„ŒνŠΈλ₯Ό μƒμ„±ν•œλ‹€.

// Test μ»΄ν¬λ„ŒνŠΈ
import React, { useState } from "react";
import { useForm } from "react-hook-form";
import Children from "./Children";

const Test = () => {
  const { register, handleSubmit, setValue } = useForm();
  const [isSunny, setIsSunny] = useState(true);
  const [gift, setGift] = useState([]);

  const getMyGift = () => {
    return gift.join(", ");
  };

  return (
    <div>
      <div>
        <span>κΈ°λ…ν’ˆμ„ κ°€μ§€κ³  μ§‘μœΌλ‘œ λŒμ•„κ°ˆ 수 μžˆμ„κΉŒμš”?</span>
        <button onClick={() => setIsSunny(!isSunny)}>날씨 λ°”κΎΈκΈ°</button>
        <div>
          {isSunny
            ? "날씨가 맀우 μ’‹λ„€μš”! λΉ„ν–‰κΈ°κ°€ 이λ₯™ν•  수 μžˆμ–΄μš” πŸ›«"
            : "νƒœν’μ΄ μ™”λ„€μš”γ… γ…  λ‚΄μΌκΉŒμ§€ κΈ°λ‹€λ €λ΄μš” β›ˆ"}
        </div>
      </div>
      <form
        onSubmit={handleSubmit(({ gift }) => {
          setGift((prev) => [...prev, gift]);
          setValue("gift", "");
        })}
      >
        <input {...register("gift")} placeholder="사고 싢은 κΈ°λ…ν’ˆ" />
        <input type="submit" value="κΈ°λ…ν’ˆ κ³ λ₯΄κΈ°" />
      </form>
      <Children getMyGift={getMyGift} />
    </div>
  );
};

export default Test;

// Children μ»΄ν¬λ„ŒνŠΈ
import React, { useState, useEffect } from "react";

const Children = ({ getMyGift }) => {
  const [myGift, setMyGift] = useState();
  useEffect(() => {
    console.log("μƒˆλ‘œμš΄ κΈ°λ…ν’ˆμ΄ μΆ”κ°€λ˜μ—ˆμŠ΅λ‹ˆλ‹€!");
    setMyGift(getMyGift());
  }, [getMyGift]);
  return <div>λ‚˜μ˜ κΈ°λ…ν’ˆ λͺ©λ‘: {myGift}</div>;
};

export default Children;

μ½”λ“œμ˜ 뢄석뢀터 ν•΄λ³΄μž.

  • λ¨Όμ € λ‚˜λŠ” useForm훅을 μ‚¬μš©ν•˜κ³  μžˆλ‹€. 이 훅은 react-hook-form λͺ¨λ“ˆμ„ μ„€μΉ˜ν•œ ν›„ μ‚¬μš©ν•  수 μžˆλ‹€. ν•΄λ‹Ή λͺ¨λ“ˆκ³Ό 훅에 λŒ€ν•΄μ„œλŠ” λ‹€λ₯Έ μ±•ν„°μ—μ„œ μžμ„Ένžˆ 닀루도둝 ν•˜κ² λ‹€.

  • isSunny와 giftλΌλŠ” stateλ₯Ό λ§Œλ“€μ—ˆλ‹€.

  • isSunny stateλŠ” 날씨 λ°”κΎΈκΈ°λ²„νŠΌμ„ 눌러 값을 λ°”κΏ€ 수 있고 값에 따라 λΉ„ν–‰κΈ°κ°€ 이λ₯™ν•  수 μžˆλŠ”μ§€ μ—†λŠ”μ§€ ν…μŠ€νŠΈλ‘œ μ•Œλ €μ£Όκ³  μžˆλ‹€.

  • gift stateλŠ” μ΄ˆκΈ°κ°’μ΄ 배열이고 inputμ—μ„œ 받은 값을 μ°¨λ‘€λŒ€λ‘œ Array.push()λ©”μ„œλ“œλ₯Ό 톡해 μ €μž₯ν•˜κ³  μžˆλ‹€.

  • getMyGift()λŠ” Childrenμ»΄ν¬λ„ŒνŠΈμ— props둜 μ „λ‹¬ν•˜λŠ” ν•¨μˆ˜μ΄λ‹€. ν•΄λ‹Ή ν•¨μˆ˜λŠ” 배열을 Array.join()λ©”μ„œλ“œλ₯Ό 톡해 λ¬Έμžμ—΄λ‘œ λ°”κΎΈλŠ” 역할을 ν•œλ‹€.

  • Childrenμ»΄ν¬λ„ŒνŠΈμ—μ„œλŠ” myGift stateκ°€ 선언이 λ˜μ–΄ μžˆλ‹€. ν•΄λ‹Ή stateλŠ” props으둜 전달받은 getMyGift()κ°€ μ—…λ°μ΄νŠΈ 될 λ•Œ λ§ˆλ‹€ useEffect() 을 톡해 μ—…λ°μ΄νŠΈ 되고 μžˆλ‹€.

μ½”λ“œ 뢄석이 λλ‚¬μœΌλ‹ˆ state값듀을 λ³€κ²½ν•˜μ—¬ 화면이 λžœλ”λ§ν•˜λŠ” 과정을 μ•Œμ•„λ³΄μž. 일단 μ œμ£Όλ„μ— κ°”μœΌλ‹ˆ κΈ°λ…ν’ˆμ„ μ‚¬μ•Όν•œλ‹€. 사고 싢은 κΈ°λ…ν’ˆμ„ μž…λ ₯ν•˜κ³  κΈ°λ…ν’ˆ κ³ λ₯΄κΈ° λ²„νŠΌμ„ 눌러 λ‚˜μ˜ κΈ°λ…ν’ˆ λͺ©λ‘μ— μΆ”κ°€ν•˜μž.

useCallback 1

초콜릿, λ¨Έκ·Έμž”, μ œμ£Όλ¦¬μ–Όνƒ€λ₯΄νŠΈ, ν–₯수λ₯Ό κΈ°λ…ν’ˆ ν’ˆλͺ©μ— μΆ”κ°€ν•˜μ˜€λ‹€. μΆ”κ°€κ°€ 될 λ•Œ λ§ˆλ‹€ getMyGift()κ°€ μƒˆλ‘œμš΄ ν•¨μˆ˜ 객체λ₯Ό ν• λ‹Ήν•˜κ³  있기 λ•Œλ¬Έμ— Childrenμ»΄ν¬λ„ŒνŠΈμ˜ useEffect()κ°€ μ‹€ν–‰λœλ‹€.

κ·Έλ ‡λ‹€λ©΄ getMyGift()와 μ „ν˜€ μƒκ΄€μ—†λŠ” isSunny의 값을 λ°”κΎΈκ²Œ 되면 μ–΄λ–»κ²Œ 될까? 날씨 λ°”κΎΈκΈ°λ²„νŠΌμ„ ν΄λ¦­ν•˜μ—¬ λΉ„ν–‰κΈ°λ₯Ό λ‹€μŒλ‚ μ— λ„μ–΄λ³΄μž.

useCallback 2

날씨가 λ°”λ€Œμ–΄ νƒœν’μ΄ 였고 μžˆλ‹€. isSunny값은 μ„±κ³΅μ μœΌλ‘œ λ°”λ€Œμ—ˆκ³  gift의 값은 λ°”λ€Œμ§€ μ•Šμ•˜λ‹€. ν•˜μ§€λ§Œ getMyGift()κ°€ μƒˆλ‘œμš΄ ν•¨μˆ˜ 객체λ₯Ό ν• λ‹Ήν•˜κ³  μžˆμ–΄ Childrenμ»΄ν¬λ„ŒνŠΈμ˜ useEffect()κ°€ 싀행이 λ˜μ—ˆλ‹€. κ·Έλž˜μ„œ μš°λ¦¬λŠ” "μƒˆλ‘œμš΄ κΈ°λ…ν’ˆμ΄ μΆ”κ°€λ˜μ—ˆμŠ΅λ‹ˆλ‹€!"λΌλŠ” ν…μŠ€νŠΈκ°€ μ½˜μ†”μ— ν•˜λ‚˜ 더 μΆ”κ°€λœ λͺ¨μŠ΅μ„ λ³Ό 수 μžˆλ‹€.

즉 λ¦¬λžœλ”λ§μ΄ ν•„μš”ν•˜μ§€ μ•ŠλŠ” μ»΄ν¬λ„ŒνŠΈμ—μ„œ λΆˆν•„μš”ν•œ λ¦¬λžœλ”λ§μ΄ μΌμ–΄λ‚œ 것이닀.

μ΄λŸ¬ν•œ μ΄μœ λŠ” useMemo()μ±•ν„°μ—μ„œ μ„€λͺ…ν–ˆμ§€λ§Œ λ‹€μ‹œ λ³΅μŠ΅ν•˜μžλ©΄, λ¦¬μ•‘νŠΈμ—μ„œμ˜ μ»΄ν¬λ„ŒνŠΈλ„ ν•˜λ‚˜μ˜ ν•¨μˆ˜μ΄λ‹€. 즉 ν•¨μˆ˜κ°€ λ¦¬λžœλ”λ§ λœλ‹€λŠ” 것은 λ³€μˆ˜κ°€ μ΄ˆκΈ°ν™”κ°€ λœλ‹€λŠ” 것이닀. 같은 역할을 ν•˜κ³  μžˆλŠ” ν•¨μˆ˜μ§€λ§Œ λ³€μˆ˜κ°€ μ°Έμ‘°ν•˜κ³  μžˆλŠ” ν•¨μˆ˜ 객체의 μ£Όμ†ŒλŠ” λ‹€λ₯΄κΈ° λ•Œλ¬Έμ΄λ‹€.


4. useCallback()λ₯Ό μ‚¬μš©ν•œ μ»΄ν¬λ„ŒνŠΈμ˜ λžœλ”λ§

이제 useCallback()훅을 μ‚¬μš©ν•˜μ—¬ μœ„μ˜ 문제λ₯Ό ν•΄κ²°ν•˜μž.

getMyGift()의 ν•¨μˆ˜λ₯Ό μ•„λž˜μ™€ 같이 μˆ˜μ •ν•˜μž.

그리고 λ‚˜μ„œ λ‹€μ‹œ κΈ°λ…ν’ˆ λͺ©λ‘μ„ μΆ”κ°€ν•΄λ³΄μž.

useCallback 3

μ΄λ²ˆμ—λ„ κΈ°λ…ν’ˆ μΆ”κ°€ 될 λ•Œλ§ˆ Childrenμ»΄ν¬λ„ŒνŠΈκ°€ λ¦¬λžœλ”λ§μ΄ λ˜λŠ” 것을 확인할 수 μžˆλ‹€. 그러면 날씨 λ°”κΎΈκΈ°λ²„νŠΌμ„ ν΄λ¦­ν•˜μ—¬ Childrenμ»΄ν¬λ„ŒνŠΈμ™€ κ΄€λ ¨μ—†λŠ” isSunny의 값을 λ°”κΎΈμ–΄ 보자.

useCallback 4

isSunny의 값이 λ°”λ€Œμ–΄ 날씨가 νƒœν’μœΌλ‘œ μ—…λ°μ΄νŠΈ λ˜μ–΄λ„ Childrenμ»΄ν¬λ„ŒνŠΈλŠ” λ¦¬λžœλ”λ§μ΄ λ˜μ§€ μ•ŠλŠ” 것을 확인할 수 μžˆλ‹€.

μ΄λŠ” useCallback()ν›…μ˜ μ˜μ‘΄μ„± λ°°μ—΄μ˜ κ°’μœΌλ‘œ gift만 μΆ”κ°€ν–ˆκΈ°μ— isSunnyκ°€ 아무리 λ°”λ€Œμ–΄λ„ getMyGift()ν•¨μˆ˜κ°€ μ°Έμ‘°ν•˜κ³  μžˆλŠ” ν•¨μˆ˜ 객체의 μ£Όμ†ŒλŠ” λ°”λ€Œμ§€ μ•ŠκΈ° λ•Œλ¬Έμ΄λ‹€.


5. Conclusion

useMemo()ν›…κ³Ό useCallback()훅을 κ³΅λΆ€ν•˜λ©΄μ„œ 느꼈던 점은 "κ³Όμ—° λ‚΄κ°€ μ μ œμ μ†Œμ— ν•΄λ‹Ή 훅을 잘 μ‚¬μš©ν•  수 μžˆμ„κΉŒ?"μ˜€λ‹€. μ§€κΈˆκΉŒμ§€ λžœλ”λ§ μ΅œμ ν™”μ— λŒ€ν•œ 고민을 ν•˜μ§€ μ•Šκ³  μ½”λ“œλ₯Ό μž‘μ„±ν–ˆκΈ° λ•Œλ¬Έμ— ν•„μš”ν•œ 곳에 λ‚΄κ°€ 잘 μ μš©μ„ ν•  수 μžˆμ„μ§€ 걱정이 λœλ‹€. κ·Έλž˜λ„ μ–Όλ₯Έ ν‹°μ²˜μΊ” λ¦¬νŒ©ν† λ§μ„ μ‹œμž‘ν•΄μ„œ 직접 ν”„λ‘œμž­νŠΈμ— μ μš©μ„ ν•˜κ³  μ‹Άλ‹€. λ¦¬νŒ©ν† λ§μ€ λ‹€μŒμ£Ό μ›”μš”μΌ(22.8.8) λΆ€ν„° μ‹œμž‘!


μ°Έκ³ 

[React] λ¦¬μ•‘νŠΈ Hooks : useCallback() ν•¨μˆ˜ μ‚¬μš©λ²• React Hooks: useCallback μ‚¬μš©λ²•

도움이 많이 λ˜μ—ˆλ˜ 유튜브 🎬

  • React Hooks에 μ·¨ν•œλ‹€ - useCallback μ§± μ‰¬μš΄ κ°•μ˜ | λ¦¬μ•‘νŠΈ ν›…μŠ€ μ‹œλ¦¬μ¦ˆ

    React Hooks에 μ·¨ν•œλ‹€ - useCallback μ§± μ‰¬μš΄ κ°•μ˜ | λ¦¬μ•‘νŠΈ ν›…μŠ€ μ‹œλ¦¬μ¦ˆ


πŸ‘†

πŸ“… 2022-08-04

Last updated