فهرست سرفصل‌های React
خانه (Home) مقدمه (Intro) شروع کار (Get Started) اولین اپ (First App) رندر HTML (Render HTML) ارتقا (Upgrade) آشنایی با ES6 (ES6) کلاس ها در ES6 (ES6 Classes) توابع پیکانی ES6 (ES6 Arrow Functions) متغیرها در ES6 (ES6 Variables) متد map روی آرایه ها (ES6 Array map()) دیس ترکچرینگ (تقسیم ساختاری) (ES6 Destructuring) عملگر پخش (Spread) (ES6 Spread Operator) ماژول ها در ES6 (ES6 Modules) عملگر سه تایی (Ternary) (ES6 Ternary Operator) رشته های قالبی (Template Strings) (ES6 Template Strings) مقدمه JSX (JSX Intro) عبارت ها در JSX (JSX Expressions) خصیصه ها در JSX (JSX Attributes) شرط ها در JSX (JSX If Statements) کامپوننت ها (Components) کلاس ها (Class) پراپس ها (Props) (Props) دیس ترکچرینگ پراپس ها (Props Destructuring) پراپس children (Props Children) رویدادها (Events) رندر شرطی (Conditionals) لیست ها (Lists) فرم ها (Forms) ارسال فرم (Forms Submit) فیلد Textarea (Textarea) فیلد Select (Select) چند ورودی در فرم (Multiple Inputs) چک باکس (Checkbox) دکمه های رادیویی (Radio) پورتال ها (Portals) Suspense (Suspense) استایل دهی با CSS (CSS Styling) CSS Modules (CSS Modules) CSS-in-JS (CSS-in-JS) مسیریابی (Router) (Router) ترنزیشن ها (Transitions) (Transitions) Forward Ref (Forward Ref) کامپوننت های مرتبه بالاتر (HOC) (HOC) استایل دهی با Sass (Sass) هوکس چیست؟ (What is Hooks?) هوک useState (useState) هوک useEffect (useEffect) هوک useContext (useContext) هوک useRef (useRef) هوک useReducer (useReducer) هوک useCallback (useCallback) هوک useMemo (useMemo) هوک های سفارشی (Custom Hooks) کامپایلر (Compiler) کوئیز (آزمون کوتاه) (Quiz) تمرین ها (Exercises) سیلابس (سرفصل دوره) (Syllabus) برنامه مطالعه (Study Plan) سرور (Server) آمادگی مصاحبه (Interview Prep) گواهینامه (Certificate)
نتیجه‌ای برای جستجو یافت نشد.
React

React — هوک useCallback (useCallback)

آخرین بروزرسانی: 1404/08/24

هوک useCallback (useCallback)

هوک useCallback در ری اکت کمک می کند تابع ها را کش (Cache) کنی تا هر بار بی خودی دوباره ساخته نشوند. این کار مخصوصاً وقتی کامپوننت های زیادی داری، رندرهای اضافه را کم می کند.

useCallback در ری اکت دقیقاً چه کار می کند؟

هوک (Hook) یعنی تابع کمکی ری اکت که به کامپوننت قدرت اضافه می کند. useCallback در ری اکت یک تابع را «مموایز (Memoize)» می کند؛ یعنی خودش را نگه می دارد تا وقتی وابستگی ها عوض نشدند، دوباره ساخته نشود.

وابستگی (Dependency) یعنی مقدارهایی که اگر عوض شوند، تابع باید دوباره ساخته شود. این تابع معمولاً همان هندلر کلیک یا تابعی است که به فرزند می فرستی.

useMemo در ری اکت مقدار مموایز شده برمی گرداند. اما useCallback در ری اکت تابع مموایز شده برمی گرداند. پس هر دو شبیه اند، فقط خروجی متفاوت است.

اگر خواستی جزئیات useMemo را ببینی، بعداً سر بزن به صفحه هوک useMemo.

سینتکس useCallback در ری اکت

طبق منبع، useCallback دو آرگومان اصلی دارد: خود تابع و آرایه وابستگی ها. اگر یکی از وابستگی ها عوض شود، تابع دوباره ساخته می شود.

useCallback(callback, dependencies);

مشاهده در ادیتور

callback همان تابعی است که می خواهی مموایز شود. dependencies آرایه ای از مقدارهاست که تغییرشان باعث ساخت نسخه تازه تابع می شود.

مثال بدون استفاده از useCallback در ری اکت

در مثال اول، یک والد و دو دکمه داری. هر دکمه یک تابع onClick می گیرد. توابع در هر رندر دوباره ساخته می شوند. با اینکه از React.memo برای فرزند استفاده شده، باز هم هر بار هر سه کامپوننت رندر می شوند.

کد مثال بدون useCallback در ری اکت

//Without useCallback:
import React, { useState } from "react";
import { createRoot } from "react-dom/client";

// Child component that receives a function prop
const Button = React.memo(({ onClick, text }) => {
  alert(`Child ${text} button rendered`);
  return <button onClick={onClick}>{text}</button>;
});

// Parent component without useCallback
function WithoutCallbackExample() {
  const [count1, setCount1] = useState(0);
  const [count2, setCount2] = useState(0);

  // This function is recreated on every render
  const handleClick1 = () => {
    setCount1(count1 + 1);
  };

  const handleClick2 = () => {
    setCount2(count2 + 1);
  };

  alert("Parent rendered");
  return (
    <div>
      <h2>Without useCallback:</h2>
      <p>Count 1: {count1}</p>
      <p>Count 2: {count2}</p>
      <Button onClick={handleClick1} text="Button 1" />
      <Button onClick={handleClick2} text="Button 2" />
    </div>
  );
}

createRoot(document.getElementById("root")).render(
  <WithoutCallbackExample />
);

مشاهده در ادیتور

طبق توضیح منبع، اگر این کد را اجرا کنی و روی دکمه ها کلیک کنی، والد و هر دو دکمه دوباره رندر می شوند. حتی وقتی فقط یکی از شمارنده ها عوض شده است.

نکته: اینجا مشکل اصلی این است که توابع handleClick1 و handleClick2 در هر رندر نسخه تازه ای می سازند. این کار باعث می شود React.memo روی کامپوننت Button خیلی کمک نکند.

استفاده از useCallback در ری اکت برای بهینه سازی

در نسخه دوم مثال، useCallback در ری اکت استفاده شده است. این بار توابع کلیک با useCallback ساخته می شوند و فقط وقتی شمارنده مربوطه عوض شود، دوباره ساخته می شوند.

کد مثال با useCallback در ری اکت

//With useCallback:
import React, { useState, useCallback } from "react";
import { createRoot } from "react-dom/client";

// Child component that receives a function prop
const Button = React.memo(({ onClick, text }) => {
  console.log(`${text} button rendered`);
  return <button onClick={onClick}>{text}</button>;
});

// Parent component with useCallback
function WithCallbackExample() {
  const [count1, setCount1] = useState(0);
  const [count2, setCount2] = useState(0);

  // These functions are memoized and only recreated when dependencies change
  const handleClick1 = useCallback(() => {
    setCount1(count1 + 1);
  }, [count1]);

  const handleClick2 = useCallback(() => {
    setCount2(count2 + 1);
  }, [count2]);

  console.log("Parent rendered");
  return (
    <div>
      <h2>With useCallback:</h2>
      <p>Count 1: {count1}</p>
      <p>Count 2: {count2}</p>
      <Button onClick={handleClick1} text="Button 1" />
      <Button onClick={handleClick2} text="Button 2" />
    </div>
  );
}

createRoot(document.getElementById("root")).render(
  <WithCallbackExample />
);

مشاهده در ادیتور

منبع می گوید حالا اگر روی Button 1 کلیک کنی، فقط والد و همان دکمه رندر می شوند. اگر روی Button 2 کلیک کنی، فقط والد و Button 2 رندر می شوند.

پس useCallback در ری اکت کمک می کند که توابعی که به فرزندها می فرستی، فقط وقتی لازم است عوض شوند. این یعنی رندر کمتر و کار سبک تر برای مرورگر.

اگر خواستی این مبحث را دوباره مرور کنی، صفحه useCallback در ری اکت در UnderDevelops را به عنوان مرجع نگه دار.

جمع بندی سریع

  • useCallback در ری اکت تابع را مموایز می کند، نه مقدار را.
  • این هوک دو ورودی دارد: خود تابع و وابستگی ها.
  • تابع فقط وقتی وابستگی ها عوض شوند، دوباره ساخته می شود.
  • کنار React.memo روی فرزند، رندرهای اضافه را کم می کند.
  • در لیست ها و کامپوننت های تو در تو، بسیار به دردبخور است.