اذهب إلى المحتوى

السؤال

Recommended Posts

  • 1
نشر (معدل)

يتم استخدام UseCallback لتحسين سلوك عرض مكوناتfunction components في React ، بينما يُستخدم useMemo لتذكر الدوال وتجنب الإضطرار إلى إستدعائها في كلrender  . كإنشاء قياسي لل hooks ، فإن هذين الحلين ليسا مختلفين تمامًا. كما هو الحال مع useEffect ،ال hook الذي يدير الآثار الجانبية في functional components ، يأتي callback أولاً ثم مصفوفة من dependencies.

بخصوص useEffect فأنه واحد من اهم ال hooks شيوعاً في الإستخدام بجانب useState. نستعمله عندما نريد إجراء تعديل على حالة ال component بعد ال render أي بعد التشغيل والإرجاع return المساوي ل render في حالة class component حيث تقوم بنفس عمل componentDidMount و أيضا تعوض عن componentDidUpdate

	const myComp= ( props ) => {
    const [name, setName]= useState('غير محدد')
    const displayMyName = () => {
         setTimeout(()=>setName("Ali"), 5000) // نصب مؤقت لتعديل قيمة الاسم بعد مرور 5 ثواني على ال rendering
    }  // عرض الأسم بعد 5 ثواني
	    useEffect(()=>displayMyName())  // استدعاءها يحصل مباشرة بعد ال rendering
    
    return( // عند التشغيل سيظهر الإسم غير محدد ثم يتم تعديله تلقائياً
      <div>My name is {name}</div>
    )
}
	


المثال أعلاه يمثل نموذج لإستعمال useEffect بمعية useState إلا إنه لا يحصر كل ما يتعلق بالإثنين.


فيما يلي مثال ومقارنة أساسية بين useCallback و useMemo:


useCallback تستدعى من قبل المطور نفسه بينما React تقوم بإستدعاء useMemo كما في المثال:

function memoUseFunc() {
  const x  = useMemo(() => {
    return <div>الجو حار</div>
  })
	  return x
}
	function callbackUseFunc() {
  const x  = useCallback((name) => {
    return <div>مرحبا {name}</div>
  })
  return x()
}

يحتوي متغير useMemo على نتيجة الإرجاع فقط ، مما يعني تجاهل كل شيء في جسم دالة الوسيطةcallback. بينما يحتوي متغير useCallback على function. إنه يستخدم ببساطةstring  ، تُعرف أيضًا ب return statement اي الراجع من الإستدعاء.
 هذا يعني أن هذين الأسلوبين يقدمان نفس النتائج. 
من الجدير بالذكر ان useMemo ليس لها parameters بعكس useCallback التي تأخذ أي عدد من الparameters وفي مثالنا أعلاه لدينا name.

يمكنك قراءة المزيد عن الموضوع في الموقع الرسمي ل React
 

تم التعديل في بواسطة علي محسن
  • 1
نشر

useEffect لها وظيفة مختلفة عن الوظيفتين الاخريين لذلك سأتحدث عنها في البداية ثم سنتحدث عن الوظيفتين الأخريين.

تستخدم useEffect كبديل عن كل من :

  • componentDidMount
    useEffect(() => { 
      console.log("سيتم طباعة هذا النص عند تحميل المكون لأول مرة فقط")  
      // لاحظ ان المصفوفة الخاصة بالمتغيرات التي يعتمد عليها الخطاف فارغة
      // وهذا هو السبب في انه يتم تنفيذ الخطاف مرة واحدة فقط
    }, []);

     

  • componentDidUpdate
    useEffect(() => { 
      console.log("سيتم طباعة هذا النص عند كل تحديث للمكون")  
      // في حال لم نضف متغيرات يعتمد عليها الخطاف فإنه سيتم تنفيذه عند كل تحديث للمكون
    });
    
    useEffect(() => { 
      console.log("سيتم طباعة هذا النص عند كل تحديث للمكون بشرط ان يحدث تغيير في قيم المتغيرات التي يعتمد عليها الخطاف")    
      // في حال وجود متغيرات يعتمد عليها الخطاف فلن يتم تنفيذه إلا في حال تغيرت هذه القيم
    },[count , date , ext]);

     

بينما الوظيفتين الاخريين useCallback و useMemo فهما خاصين بإسناد قيم ثابتة ولا تتغير وبالتالي الحفاظ على الأداء الجيد للتطبيق، بحيث لا يتم تنفيذ الاكواد الخاص بهم إلا مرة واحدة أو عند تحقق شرط معين.

لاحظ المثال التالي والذي يحتوي الوظيفة expensiveCalculation التي تستهلك الكثير من الأداء و تبطء التطبيق بالكامل live Demo :

import { useState } from "react";
import ReactDOM from "react-dom/client";

const App = () => {
  const [count, setCount] = useState(0);
  const [todos, setTodos] = useState([]);
  const calculation = expensiveCalculation(count);

  const increment = () => {
    setCount((c) => c + 1);
  };
  const addTodo = () => {
    setTodos((t) => [...t, "New Todo"]);
  };

  return (
    <div>
      <div>
        <h2>My Todos</h2>
        {todos.map((todo, index) => {
          return <p key={index}>{todo}</p>;
        })}
        <button onClick={addTodo}>Add Todo</button>
      </div>
      <hr />
      <div>
        Count: {count}
        <button onClick={increment}>+</button>
        <h2>Expensive Calculation</h2>
        {calculation}
      </div>
    </div>
  );
};

const expensiveCalculation = (num) => {
  console.log("Calculating...");
  for (let i = 0; i < 1000000000; i++) {
    num += 1;
  }
  return num;
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

وهذا هو التطبيق نفسه بعد استخدام useMemo :

import { useState, useMemo } from "react";
import ReactDOM from "react-dom/client";

const App = () => {
  const [count, setCount] = useState(0);
  const [todos, setTodos] = useState([]);
  const calculation = useMemo(() => expensiveCalculation(count), [count]);

  const increment = () => {
    setCount((c) => c + 1);
  };
  const addTodo = () => {
    setTodos((t) => [...t, "New Todo"]);
  };

  return (
    <div>
      <div>
        <h2>My Todos</h2>
        {todos.map((todo, index) => {
          return <p key={index}>{todo}</p>;
        })}
        <button onClick={addTodo}>Add Todo</button>
      </div>
      <hr />
      <div>
        Count: {count}
        <button onClick={increment}>+</button>
        <h2>Expensive Calculation</h2>
        {calculation}
      </div>
    </div>
  );
};

const expensiveCalculation = (num) => {
  console.log("Calculating...");
  for (let i = 0; i < 1000000000; i++) {
    num += 1;
  }
  return num;
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

انظر الـ live Demo وانظر الفرق بالأداء بين هذا الكود والكود السابق.

و useCallback تفرق عن useMemo في انها تعيد وظيفة وليس قيمة مفردة.

إطلع على :

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...