We want to hear from you!Take our 2021 Community Survey!
This site is no longer updated.Go to react.dev

Invalid Hook Call Warning

أنت على الأرجح هُنا بسبب الخطأ التالي:

Hooks can only be called inside the body of a function component.
يُمكن استِدعاء الخطافات فقط داخل مُكوّن دالّة.

هُناك ثلاثة أسباب شائعه لظهور الخطأ أعلاه:

  1. لِديك نُسخ غير مُتوافقة من React و React DOM.
  2. قد تكون تخرق قواعد الخطافات.
  3. من المُحتمل أن يكون لديك أكثر من نسخة 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 التي يُصييرهُ.

أسباب أُخرى

إن كُنت لازلت تواجه المشاكل، الرجاء ترك تعليف في هذه التذكره وسَنُحاول مُساعدَتُك. إن أمكن، حاوِل انشاء مثال لإعادة إنتاج الخطأ فقد تكتشف المُشكلة حينها.

Is this page useful?تحرير هذه الصفحة