الفرق بين المراجعتين لصفحة: «React/hooks rules»

من موسوعة حسوب
إنشاء الصفحة.
 
تحديث
 
(مراجعتان متوسطتان بواسطة مستخدم واحد آخر غير معروضتين)
سطر 2: سطر 2:
''الخطافات هي إضافة جديدة إلى الإصدار 16.8 في React، إذ تسمح لك باستعمال ميزة الحالة وميزات React الأخرى دون كتابة أي صنف.''
''الخطافات هي إضافة جديدة إلى الإصدار 16.8 في React، إذ تسمح لك باستعمال ميزة الحالة وميزات React الأخرى دون كتابة أي صنف.''


الخطافات هي دوال جافاسكربت، ولكن تحتاج إلى اتباع قاعدتين عند استعمالها. نوفر [https://www.npmjs.com/package/eslint-plugin-react-hooks إضافة تصحيح أخطاء الصياغة] تجبرك على تطبيق هاتين القاعدتين تلقائيًّا.
الخطافات هي دوال [[JavaScript]]، ولكن تحتاج إلى اتباع قاعدتين عند استعمالها. نوفر [https://www.npmjs.com/package/eslint-plugin-react-hooks إضافة تصحيح أخطاء الصياغة] تجبرك على تطبيق هاتين القاعدتين تلقائيًّا.


== استدعي الخطافات في المستوى الأعلى فقط ==
== استدعي الخطافات في المستوى الأعلى فقط ==
لا تستدعي الخطاففات داخل حلقات التكرار، أو التعابير الشرطية، أو الدوال المتعشبة. بدلًا من ذلك، استعملالخطافات دومًأ في المستوى الأعلى (top level) من دالة React. بتطبيق هذه القاعدة، تتأكد من أن الخطافات تُستدَعى بالترتيب نفسه في كل مرة يصيَّر فيها مكونٌ. هذا يسمح لـ React بحفظ حالة الخطافات بين الاستدعاءات useState و useEffect المتعددة بشكل صحيح. (إن شدَّك فضولك للتعلم أكثر، سنشرح هذا الأمر بالتفصيل في الأسفل.)
لا تستدعي الخطافات داخل حلقات التكرار، أو التعابير الشرطية، أو الدوال المتعشبة. بدلًا من ذلك، استعمل الخطافات دومًا في المستوى الأعلى (top level) من دالة [[React]]. بتطبيق هذه القاعدة، تتأكد من أن الخطافات تُستدَعى بالترتيب نفسه في كل مرة يصيَّر فيها مكونٌ. هذا يسمح لـ [[React]] بحفظ حالة الخطافات بين الاستدعاءات <code>[[React/hooks state|useState]]</code> و <code>[[React/hooks effect|useEffect]]</code> المتعددة بشكل صحيح. (إن شدَّك فضولك للتعلم أكثر، سنشرح هذا الأمر بالتفصيل في الأسفل.)


== استدعي الخطافات من دوال React فقط ==
== استدعي الخطافات من دوال React فقط ==
لا تستدعي الخطافات من دوال جافاسكربت العادية. بدلًا من ذلك، يمكنك:
لا تستدعي الخطافات من دوال [[JavaScript|JavaScript]] العادية. بدلًا من ذلك، يمكنك:
* استدعاء الخطافات من مكونات دالة React.
* استدعاء الخطافات من مكونات دالة [[React]].
* استدعاء الخطافات من خطافات مخصصة (سنتعرف عليهم في [[React/hooks custom|الصفحة التالية]]).
* استدعاء الخطافات من خطافات مخصصة (سنتعرف عليهم في [[React/hooks custom|الصفحة التالية]]).
باتباع هذه القاعدة، تتأكد من أنَّ الشيفرة ذات الحالة (stateful logic) في مكونٍ ما مرئيةٌ بوضوح من شيفرتها المصدرية.
باتباع هذه القاعدة، تتأكد من أنَّ الشيفرة ذات الحالة (stateful logic) في مكونٍ ما مرئيةٌ بوضوح من شيفرتها المصدرية.


== الإضافة ESLint ==
== الإضافة ESLint ==
أطلقنا إضافة لتصحيح الأخطاء تدعى [https://www.npmjs.com/package/eslint-plugin-react-hooks eslint-plugin-react-hooks] تجبر على تطبيق هاتين القاعدتين. يمكنك إضافة هذه الإضافة إلى مشروعك إن أحببت تجريبها:<syntaxhighlight lang="shell">
أطلقنا إضافةً لتصحيح الأخطاء تدعى [https://www.npmjs.com/package/eslint-plugin-react-hooks eslint-plugin-react-hooks] تجبر على تطبيق هاتين القاعدتين. يمكنك إضافة هذه الإضافة إلى مشروعك إن أحببت تجريبها:<syntaxhighlight lang="shell">
npm install eslint-plugin-react-hooks
npm install eslint-plugin-react-hooks


سطر 26: سطر 26:
   "rules": {
   "rules": {
     // ...
     // ...
     "react-hooks/rules-of-hooks": "error"
     "react-hooks/rules-of-hooks": "error", // تحقق من قواعد الخطاف
    "react-hooks/exhaustive-deps": "warn" // dependencies تحقق من تأثيرات الاعتماديات
   }
   }
}
}
</syntaxhighlight>في المستقبل، ننوي تضمين هذه الإضافة افتراضيًّا عند بناء تطبيقات جديدة باستعمال الأمر [http://github.com/facebookincubator/create-react-app create-react-app] أو أية مجموعة أدوات أخرى (toolkits).
</syntaxhighlight>يمكنك تخطي بقية هذه الصفحة إلى الصفحة التالية: "[[React/hooks custom|بناء خطافات خاصة بك]]" الآن، إذ سنكمل شرح سبب وجود هاتين القاعدتين.
 
يمكنك تخطي بقية هذه الصفحة إلى الصفحة التالية: "[[React/hooks custom|بناء خطافات خاصة بك]]" الآن، إذ سنكمل شرح سبب وجود هاتين القاعدتين.


== سبب تطبيق هاتين القاعدتين ==
== سبب تطبيق هاتين القاعدتين ==
سطر 54: سطر 53:
   // ...
   // ...
}
}
</syntaxhighlight>إذًا، كيف تعرف React أية حالة توافق أي استدعاء للخطاف useState؟ الجواب هو أن React تعتمد على الترتيب الذي استدعيت الخطافات به. مثالنا السابق يعمل بشكل صحيح لأن ترتيب استدعاء الخطافات هو نفسه في كل تصيير:<syntaxhighlight lang="javascript">
</syntaxhighlight>إذًا، كيف تعرف [[React]] أية حالة توافق أي استدعاء للخطاف <code>useState</code>؟ الجواب هو أنَّ [[React]] تعتمد على الترتيب الذي استدعيت الخطافات به. مثالنا السابق يعمل بشكل صحيح لأنَّ ترتيب استدعاء الخطافات هو نفسه في كل تصيير:<syntaxhighlight lang="javascript">
// ------------
// ------------
// أول تصيير
// أول تصيير
سطر 72: سطر 71:


// ...
// ...
</syntaxhighlight>طالمًا أن ترتيب استدعاءات الخطاف هو نفسه بين عمليات التصيير، تستطيع React من ربط بعض الحالات المحلية مع بعضها بعضًا. ولكن، ماذا يحصل إن وضعنا استدعاء خطاف (التأثير persistForm مثلًا) داخل تعبير شرطي؟<syntaxhighlight lang="javascript">
</syntaxhighlight>طالمًا أنَّ ترتيب استدعاءات الخطاف هو نفسه بين عمليات التصيير، تستطيع [[React]] من ربط بعض الحالات المحلية مع بعضها بعضًا. ولكن، ماذا يحصل إن وضعنا استدعاء خطاف (التأثير <code>persistForm</code> مثلًا) داخل تعبير شرطي؟<syntaxhighlight lang="javascript">
   // نكسر الآن القاعدة الأولى عبر استعمال خطاف داخل تعبير شرطي
   // نكسر الآن القاعدة الأولى عبر استعمال خطاف داخل تعبير شرطي
   if (name !== '') {
   if (name !== '') {
سطر 79: سطر 78:
     });
     });
   }
   }
</syntaxhighlight>الشرط name !== <nowiki>''</nowiki> هو true في عملية التصيير الأولى، لذا يُنفَّذ هذا الخطاف. مع ذلك، في عملية التصيير التالية، قد يمسح المستخدم النموذج مما يؤدي إلى تغيِّر قيمة الشرط إلى false. الآن وبعد أن تخطينا هذا الخطاف أثناء عملية التصيير، أصبح ترتيب استدعاءات الخطاف مختلفًا:<syntaxhighlight lang="javascript">
</syntaxhighlight>الشرط <code>name !== <nowiki>''</nowiki>‎</code> هو <code>true</code> في عملية التصيير الأولى، لذا يُنفَّذ هذا الخطاف. مع ذلك، في عملية التصيير التالية، قد يمسح المستخدم النموذج مما يؤدي إلى تغيِّر قيمة الشرط إلى <code>false</code>. الآن وبعد أن تخطينا هذا الخطاف أثناء عملية التصيير، أصبح ترتيب استدعاءات الخطاف مختلفًا:<syntaxhighlight lang="javascript">
useState('Mary')          // 1. (يتجاهل الوسيط) name قراءة متغير الحالة
useState('Mary')          // 1. (يتجاهل الوسيط) name قراءة متغير الحالة
// useEffect(persistForm)  // يُتخطَى هذا الخطاف
// useEffect(persistForm)  // يُتخطَى هذا الخطاف
useState('Poppins')        // 2 (يجب أن تكون 3) surname فشل قراءة متغير الحالة
useState('Poppins')        // 2 (يجب أن تكون 3) surname فشل قراءة متغير الحالة
useEffect(updateTitle)    // 3 (فشل استبدال التأثير (يجب أن تكون 4
useEffect(updateTitle)    // 3 (فشل استبدال التأثير (يجب أن تكون 4
</syntaxhighlight>لن تعرف React ما الذي ستعيده من أجل استدعاء الخطاف useState الثاني. تتوقع React أن استدعاء الخطاف الثاني في هذا المكون يقابل التأثير persistForm مثل عملية التصيير السابقة، ولكن الحالة الآن لم تعد مشابه لها. بدءًا من تلك النقطة، كل استدعاء خطاف لاحق بعد ذلك الخطاف الذي جرى تخطيه سينزاح بمقدار مرةً واحدةً مما يؤدي إلى حصول أخطاء.
</syntaxhighlight>لن تعرف [[React]] ما الذي ستعيده من أجل استدعاء الخطاف <code>useState</code> الثاني. تتوقع [[React]] أن استدعاء الخطاف الثاني في هذا المكون يقابل التأثير <code>persistForm</code> مثل عملية التصيير السابقة، ولكن الحالة الآن لم تعد مشابه لها. بدءًا من تلك النقطة، كل استدعاء خطاف لاحق بعد ذلك الخطاف الذي جرى تخطيه سينزاح مرةً واحدةً مما يؤدي إلى حصول أخطاء.


هذا هو سبب وجوب استدعاء الخطافات في المستوى الأعلى من مكوناتنا. إن أردنا تنفيذ تأثير شرطيًّا، يمكننا وضع هذا الشرط داخل خطافنا:<syntaxhighlight lang="javascript">
هذا هو سبب وجوب استدعاء الخطافات في المستوى الأعلى من مكوناتنا. إن أردنا تنفيذ تأثير شرطيًّا، يمكننا وضع هذا الشرط داخل خطافنا:<syntaxhighlight lang="javascript">
سطر 93: سطر 92:
     }
     }
   });
   });
</syntaxhighlight>لاحظ أنه لا داعي للقلق حول هذه المشكلة إن كنت تستعمل [https://www.npmjs.com/package/eslint-plugin-react-hooks إضافة التصحيح] الذي أشرنا إليها في الأعلى. على أية، أصبحت الآن تعرف سبب عمل الخطافات بهذه الطريقة، وما هي المشكلات التي تمنع القاعدة من حدوثها.
</syntaxhighlight>لاحظ أنَّه لا داعي للقلق حول هذه المشكلة إن كنت تستعمل [https://www.npmjs.com/package/eslint-plugin-react-hooks إضافة التصحيح] الذي أشرنا إليها في الأعلى. على أية، أصبحت الآن تعرف سبب عمل الخطافات بهذه الطريقة، وما هي المشكلات التي تمنع القاعدة من حدوثها.


== الخطوات التالية ==
== الخطوات التالية ==
أخيرًا، أصبحنا جاهزين لكتابة لنتعلم كيفية كتابة خطافات مخصصة تخدم الغرض الذي نريد. الخطافات المخصصة تمكننا من دمج الخطافات التي توفرها React سويةً، وإعادة استعمال شيفرة شائعة ذات حالة بين مختلف المكونات.
أخيرًا، أصبحنا جاهزين لنتعلم كيفية كتابة [[React/hooks custom|خطافات مخصصة]] تخدم الغرض الذي نريد. الخطافات المخصصة تمكِّننا من دمج الخطافات التي توفرها [[React]] سويةً، وإعادة استعمال شيفرة شائعة ذات حالة بين مختلف المكونات.


== انظر أيضًا ==
*[[React/hooks intro|مدخل إلى الخطافات]]
*[[React/hooks overview|لمحة خاطفة عن الخطافات]]
*[[React/hooks state|استعمال خطاف الحالة]]
*[[React/hooks effect|استعمال خطاف التأثير]]
*[[React/hooks custom|بناء خطافات خاصة بك]]
*[[React/hooks reference|مرجع إلى الواجهة البرمجية للخطافات]]
*[[React/hooks faq|الأسئلة الشائعة حول الخطافات]]
== مصادر ==
== مصادر ==
* [https://reactjs.org/docs/hooks-rules.html صفحة قواعد استعمال الخطافات في توثيق React الرسمي.]
* [https://reactjs.org/docs/hooks-rules.html صفحة قواعد استعمال الخطافات في توثيق React الرسمي.]
[[تصنيف:React]]
[[تصنيف:React]]
[[تصنيف:React Hooks]]
[[تصنيف:React Hooks]]

المراجعة الحالية بتاريخ 11:38، 6 نوفمبر 2020

الخطافات هي إضافة جديدة إلى الإصدار 16.8 في React، إذ تسمح لك باستعمال ميزة الحالة وميزات React الأخرى دون كتابة أي صنف.

الخطافات هي دوال JavaScript، ولكن تحتاج إلى اتباع قاعدتين عند استعمالها. نوفر إضافة تصحيح أخطاء الصياغة تجبرك على تطبيق هاتين القاعدتين تلقائيًّا.

استدعي الخطافات في المستوى الأعلى فقط

لا تستدعي الخطافات داخل حلقات التكرار، أو التعابير الشرطية، أو الدوال المتعشبة. بدلًا من ذلك، استعمل الخطافات دومًا في المستوى الأعلى (top level) من دالة React. بتطبيق هذه القاعدة، تتأكد من أن الخطافات تُستدَعى بالترتيب نفسه في كل مرة يصيَّر فيها مكونٌ. هذا يسمح لـ React بحفظ حالة الخطافات بين الاستدعاءات useState و useEffect المتعددة بشكل صحيح. (إن شدَّك فضولك للتعلم أكثر، سنشرح هذا الأمر بالتفصيل في الأسفل.)

استدعي الخطافات من دوال React فقط

لا تستدعي الخطافات من دوال JavaScript العادية. بدلًا من ذلك، يمكنك:

  • استدعاء الخطافات من مكونات دالة React.
  • استدعاء الخطافات من خطافات مخصصة (سنتعرف عليهم في الصفحة التالية).

باتباع هذه القاعدة، تتأكد من أنَّ الشيفرة ذات الحالة (stateful logic) في مكونٍ ما مرئيةٌ بوضوح من شيفرتها المصدرية.

الإضافة ESLint

أطلقنا إضافةً لتصحيح الأخطاء تدعى eslint-plugin-react-hooks تجبر على تطبيق هاتين القاعدتين. يمكنك إضافة هذه الإضافة إلى مشروعك إن أحببت تجريبها:

npm install eslint-plugin-react-hooks
// الخاص بك ESLint ضبط الإضافة
{
  "plugins": [
    // ...
    "react-hooks"
  ],
  "rules": {
    // ...
    "react-hooks/rules-of-hooks": "error", // تحقق من قواعد الخطاف
    "react-hooks/exhaustive-deps": "warn" // dependencies تحقق من تأثيرات الاعتماديات
  }
}

يمكنك تخطي بقية هذه الصفحة إلى الصفحة التالية: "بناء خطافات خاصة بك" الآن، إذ سنكمل شرح سبب وجود هاتين القاعدتين.

سبب تطبيق هاتين القاعدتين

كما تعلمنا سابقًا، يمكننا استعمال خطافات حالة أو تأثير متعددة في مكون واحد:

function Form() {
  // 1. نفسه name استعمال متغير الحالة 
  const [name, setName] = useState('Mary');

  // 2. استعمال تأثير من أجل استمرار النموذج
  useEffect(function persistForm() {
    localStorage.setItem('formData', name);
  });

  // 3. surname استعمال متغير الحالة
  const [surname, setSurname] = useState('Poppins');

  // 4. استعمال تأثير من أجل تحديث العنوان
  useEffect(function updateTitle() {
    document.title = name + ' ' + surname;
  });

  // ...
}

إذًا، كيف تعرف React أية حالة توافق أي استدعاء للخطاف useState؟ الجواب هو أنَّ React تعتمد على الترتيب الذي استدعيت الخطافات به. مثالنا السابق يعمل بشكل صحيح لأنَّ ترتيب استدعاء الخطافات هو نفسه في كل تصيير:

// ------------
// أول تصيير
// ------------
useState('Mary')           // 1. 'Mary' إلى name ضبط متغير الحالة
useEffect(persistForm)     // 2. persistForm إضافى تأثير من أجل استمرار النموذج
useState('Poppins')        // 3. 'Poppins' إلى surname ضبط متغير الحالة
useEffect(updateTitle)     // 4. إضافة تأثير من أجل تحديث العنوان

// -------------
// ثاني تصيير
// -------------
useState('Mary')           // 1. (يتجاهل الوسيط) name قراءة متغير الحالة
useEffect(persistForm)     // 2. استبدال التأثير من أجل استمرار النموذج
useState('Poppins')        // 3. (يتجاهل الوسيط) surname قراءة متغير الحالة
useEffect(updateTitle)     // 4. استبدال التأثير من أجل تحديث العنوان

// ...

طالمًا أنَّ ترتيب استدعاءات الخطاف هو نفسه بين عمليات التصيير، تستطيع React من ربط بعض الحالات المحلية مع بعضها بعضًا. ولكن، ماذا يحصل إن وضعنا استدعاء خطاف (التأثير persistForm مثلًا) داخل تعبير شرطي؟

  // نكسر الآن القاعدة الأولى عبر استعمال خطاف داخل تعبير شرطي
  if (name !== '') {
    useEffect(function persistForm() {
      localStorage.setItem('formData', name);
    });
  }

الشرط name !== ''‎ هو true في عملية التصيير الأولى، لذا يُنفَّذ هذا الخطاف. مع ذلك، في عملية التصيير التالية، قد يمسح المستخدم النموذج مما يؤدي إلى تغيِّر قيمة الشرط إلى false. الآن وبعد أن تخطينا هذا الخطاف أثناء عملية التصيير، أصبح ترتيب استدعاءات الخطاف مختلفًا:

useState('Mary')           // 1. (يتجاهل الوسيط) name قراءة متغير الحالة
// useEffect(persistForm)  // يُتخطَى هذا الخطاف
useState('Poppins')        // 2 (يجب أن تكون 3) surname فشل قراءة متغير الحالة
useEffect(updateTitle)     // 3 (فشل استبدال التأثير (يجب أن تكون 4

لن تعرف React ما الذي ستعيده من أجل استدعاء الخطاف useState الثاني. تتوقع React أن استدعاء الخطاف الثاني في هذا المكون يقابل التأثير persistForm مثل عملية التصيير السابقة، ولكن الحالة الآن لم تعد مشابه لها. بدءًا من تلك النقطة، كل استدعاء خطاف لاحق بعد ذلك الخطاف الذي جرى تخطيه سينزاح مرةً واحدةً مما يؤدي إلى حصول أخطاء. هذا هو سبب وجوب استدعاء الخطافات في المستوى الأعلى من مكوناتنا. إن أردنا تنفيذ تأثير شرطيًّا، يمكننا وضع هذا الشرط داخل خطافنا:

  useEffect(function persistForm() {
    // 👍 لم نخرق القاعدة الأولى
    if (name !== '') {
      localStorage.setItem('formData', name);
    }
  });

لاحظ أنَّه لا داعي للقلق حول هذه المشكلة إن كنت تستعمل إضافة التصحيح الذي أشرنا إليها في الأعلى. على أية، أصبحت الآن تعرف سبب عمل الخطافات بهذه الطريقة، وما هي المشكلات التي تمنع القاعدة من حدوثها.

الخطوات التالية

أخيرًا، أصبحنا جاهزين لنتعلم كيفية كتابة خطافات مخصصة تخدم الغرض الذي نريد. الخطافات المخصصة تمكِّننا من دمج الخطافات التي توفرها React سويةً، وإعادة استعمال شيفرة شائعة ذات حالة بين مختلف المكونات.

انظر أيضًا

مصادر