رد الفعل useEffectهوكس


يسمح useEffectلك الخطاف بأداء آثار جانبية في مكوناتك.

بعض الأمثلة على الآثار الجانبية هي: جلب البيانات ، وتحديث DOM مباشرة ، وأجهزة ضبط الوقت.

useEffectيقبل حجتين. الحجة الثانية اختيارية.

useEffect(<function>, <dependency>)


دعنا نستخدم عداد الوقت كمثال.

مثال:

تُستخدم setTimeout()لحساب ثانية واحدة بعد التصيير الأولي:

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setTimeout(() => {
      setCount((count) => count + 1);
    }, 1000);
  });

  return <h1>I've rendered {count} times!</h1>;
}

ReactDOM.render(<Timer />, document.getElementById('root'));

لكن انتظر!! أستمر في العد على الرغم من أنه يجب أن يعد مرة واحدة فقط!

useEffectيعمل على كل تصيير. هذا يعني أنه عندما يتغير العدد ، يحدث تصيير ، والذي يؤدي بعد ذلك إلى تأثير آخر.

ليس هذا ما نريد. هناك عدة طرق للتحكم في وقت حدوث الآثار الجانبية.

يجب علينا دائمًا تضمين المعامل الثاني الذي يقبل المصفوفة. يمكننا اختياريًا تمرير التبعيات إلى useEffectهذه المجموعة.

1. لم تمر أي تبعية:

useEffect(() => {
  //Runs on every render
});

2. مصفوفة فارغة:

useEffect(() => {
  //Runs only on the first render
}, []);

3. الدعامات أو قيم الحالة:

useEffect(() => {
  //Runs on the first render
  //And any time any dependency value changes
}, [prop, state]);

لذا ، لإصلاح هذه المشكلة ، دعنا فقط نشغل هذا التأثير على العرض الأولي.

مثال:

قم بتشغيل التأثير على العرض الأولي فقط:

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setTimeout(() => {
      setCount((count) => count + 1);
    }, 1000);
  }, []); // <- add empty brackets here

  return <h1>I've rendered {count} times!</h1>;
}

ReactDOM.render(<Timer />, document.getElementById('root'));

مثال:

فيما يلي مثال على useEffectخطاف يعتمد على متغير. إذا تم countتحديث المتغير ، فسيتم تشغيل التأثير مرة أخرى:

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function Counter() {
  const [count, setCount] = useState(0);
  const [calculation, setCalculation] = useState(0);

  useEffect(() => {
    setCalculation(() => count * 2);
  }, [count]); // <- add the count variable here

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={() => setCount((c) => c + 1)}>+</button>
      <p>Calculation: {calculation}</p>
    </>
  );
}

ReactDOM.render(<Counter />, document.getElementById('root'));

إذا كان هناك العديد من التبعيات ، فيجب تضمينها في useEffectمصفوفة التبعية.


w3schools CERTIFIED . 2022

الحصول على شهادة!

أكمل وحدات React ، ونفّذ التمارين ، وخذ الامتحان واحصل على شهادة w3schools !!

95 دولارًا ENROLL

تنظيف التأثير

تتطلب بعض التأثيرات تنظيفًا لتقليل تسرب الذاكرة.

يجب التخلص من المهلات والاشتراكات ومستمعي الأحداث والتأثيرات الأخرى التي لم تعد ضرورية.

نقوم بذلك عن طريق تضمين دالة إرجاع في نهاية useEffectالخطاف.

مثال:

قم بتنظيف المؤقت في نهاية useEffectالخطاف:

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    let timer = setTimeout(() => {
    setCount((count) => count + 1);
  }, 1000);

  return () => clearTimeout(timer)
  }, []);

  return <h1>I've rendered {count} times!</h1>;
}

ReactDOM.render(<Timer />, document.getElementById("root"));

ملاحظة: لمسح المؤقت ، كان علينا تسميته.


اختبر نفسك مع التمارين

ممارسه الرياضه:

ما الذي تحتاج إلى إضافته إلى الوسيطة الثانية للخطاف useEffectلقصره على العرض الأول فقط؟

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function App() {
  const [data, setData] = useState([]);

  useEffect(() => {
    setData(getData())
  }, );

  return <DisplayData data={data} />;
}

ReactDOM.render(<App />, document.getElementById('root'));