Invalid Hook Call Warning
أنت على الأرجح هُنا بسبب الخطأ التالي:
Hooks can only be called inside the body of a function component.
يُمكن استِدعاء الخطافات فقط داخل مُكوّن دالّة.
هُناك ثلاثة أسباب شائعه لظهور الخطأ أعلاه:
- لِديك نُسخ غير مُتوافقة من React و React DOM.
- قد تكون تخرق قواعد الخطافات.
- من المُحتمل أن يكون لديك أكثر من نسخة React في نفس التطبيق.
دَعنا ننظُر إلى كُل من الحالات أعلاه.
نُسخ غير مُتوافقة من React و React DOM
قد تكون تستخدم نسخة react-dom
أقل من v16.8.0 أو نُسخة react-native
أقل من 0.59 واللَّتَانِ لا يدعمان الخطافات بعد. يُمكنك تنفيذ “run” أمر npm ls react-dom
أو npm ls react-native
في مُجلّد التطبيق خاصتك لمعرفة النُسخة التي تستخدمها. إن وجدت أكثر من نُسخة فقد يخلق ذلك مشاكل (المزيد على ذلك أدناه).
خرق قواعد الخطافات
يُكمنك استدعاء الخظافات رَيْثَمَا تٌصيير React مكوّن دالّة فقط:
- ✅ استدعيهم في المُتسوى الأعلى من بدن “body” مُكوّن الداّلة:
- ✅ استدعيهم في المُستوى الأعلى من بدن خطاف مُخَصص.
تَعلّم المزيد عن ذلك في قواعد الخطافات
function Counter() {
// ✅ Good: top-level in a function component const [count, setCount] = useState(0); // ...
}
function useWindowWidth() {
// ✅ Good: top-level in a custom Hook const [width, setWidth] = useState(window.innerWidth); // ...
}
لِتَجنُّب الإرباك ، استدعاء الخطافات في الحالات الأُخرى ليس مدعومًا:
- 🔴 لا تَستدعِ الخطافات في مكوّنات الصنف.
- 🔴 لا تستدعِ الخطافات في مُعامِلات الأحداث “event handlers”.
- 🔴 لا تستدعِ الخطافات داخل الدوال المُمَرَرة إلى
useMemo
أوuseReducer
أوuseEffect
.
إن خرقت تلك القواعد فمن المُمكن ان ترى هذا الخطأ.
function Bad1() {
function handleClick() {
// 🔴 Bad: inside an event handler (to fix, move it outside!) const theme = useContext(ThemeContext); }
// ...
}
function Bad2() {
const style = useMemo(() => {
// 🔴 Bad: inside useMemo (to fix, move it outside!) const theme = useContext(ThemeContext); return createStyle(theme);
});
// ...
}
class Bad3 extends React.Component {
render() {
// 🔴 Bad: inside a class component useEffect(() => {}) // ...
}
}
يُمكنك استخدام مُلحق eslint-plugin-react-hooks
plugin لألتقاط بعضًا من هذه الأخطاء.
مُلاحظة
الخطافات المُخصّصة من المُحتمل أن تستدعي خطافات أُخرى (فذلك هو الهدف منها أساسًا). يعمل ذلك لأنه من المفروض أن الخطافات المُخصّصة تُستدعى فقط رَيْثَمَا يُصّيَّر يكون مكوّن الدالّة.
نُسخَتين مِن React
حتى تعمل الخطافات ، يجب ان يكون امر الاستيراد “import” في شيفرة التطبيق خاصّتِك يُحَلَّل “resolve” إلى نفس الواجهة “module” التي في أمر الاستيراد داخل حُزمة react-dom
.
إن حُلِّلا أمرا استيراد react
إلى كائنين تصدير مُختَلِفَين ، فأنك سترى هذا الخطأ. يحدث ذلك إن كانت لديك نسختان من حُزمة react
.
إن كُنت تستخدم Node لتنظيم الحُزم “package management” ، فيُكمنك تنفيذ الأمر الفحص التالي في مُجلّد المشروح خاصّتك:
npm ls react
إن كُنت ترى أكثر من React واحدة فيجب عليك إكتشاف سبب حصول ذلك و إصلاح شًجرة الإعتماديات خاصّتك “dependency tree”. فمن المُمكن أن تكون مَكتبة تَستخدِمُها تُحدد react
كأعتمادية مُباشِرة بدلًا من تحديدها كأعتمادية نظيرة. حتى يتم إصلاح تِلك المَكتبة فأن اقتِراحات Yarn تُعتبر حلًا بديلًا.
يُمكنك أيضًا مُعالجة هذه المُشكلة من خلال إضافة بعض السجلات “logs” و إعادة تشغيل خادِم التطوير “development server”:
// Add this in node_modules/react-dom/index.js
window.React1 = require('react');
// Add this in your component file
require('react-dom');
window.React2 = require('react');
console.log(window.React1 === window.React2);
إن طُبِعَ false
فأنّه من المُمكن أن يكون لديك اثنان من React و عليك معرفة سبب حصول ذلك. هذه التذكره “issue” تحتوي على بعض الأسباب الشائعة.
هذه المُشكلة قد تظهر عند تنفيذك لأمر npm link
أو أمرًا مشابه له. في تلك الحالة ، فأن المُجَمِّع “bundler” قد يَرى اثنان React - واحدة في مُجلّد التطبيق والأُخرى في مُجلّد المكتبة. اعتِبارًا myapp
و mylib
مُجلّدان إخوة (على نفس المُستوى) فقد يكون تنفيذ أمر npm link ../myapp/node_modules/react
من mylib
حلًا مُحتَملًا. يقوم ذلك بجعل المكتبة تستخدم نسخة React للتطبيق.
ملاحظة
غالبًا ، تدعم React استخدام نُسخ مُتعددة مُنفصة على صفحة واحدة (فمثلا، تُستَخدَم React من قِبَل كل من تطبيق وواجهة من الطرف الثالث “third-party widget”). تَحدُث المشاكل فقط عندما يُحَلَّل
require('react')
إلى نتيجة مُختلفة في المُكوّن عمّا يُحَلَّل من نُسخةreact-dom
التي يُصييرهُ.
أسباب أُخرى
إن كُنت لازلت تواجه المشاكل، الرجاء ترك تعليف في هذه التذكره وسَنُحاول مُساعدَتُك. إن أمكن، حاوِل انشاء مثال لإعادة إنتاج الخطأ فقد تكتشف المُشكلة حينها.