ReactJS. تحذير: لا يمكن إجراء تحديث حالة رد الفعل على مكون غير مُركب. هذه ليست عملية ، لكنها تشير إلى مذكرة

يوم جيد ، هبر! يجتمع

جميع مطوري ردود الفعل الذين يتعاملون مع التفاعل بين الظهر والأمام عاجلاً أم آجلاً ، أو التقوا ، أو سيواجهون الخطأ التالي:


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

في الواقع ، كل شيء بسيط للغاية ، ما عليك سوى الانتباه إلى العبارات التالية:

  1. تعذر تنفيذ تحديث الحالة
  2. مكون غير مثبت ؛
  3. إلغاء جميع الاشتراكات والمهام غير المتزامنة
  4. استخدم تأثير التنظيف


في قلب خطاف. اذهب تحت قطع!

وبالتالي:

  1. جميع المبرمجين المتفاعلين يعرفون ما هي الحالة (الحالة) وأن مثل هذا التحديث (setState) أيضًا. لن أكون ذلك.
  2. . :
    1) ;
    2) ;
    3) ;
    — 3 . .
  3. . - , : . , async/await — .
  4. useEffect. return () => {} useEffect. , - , : .




دعنا نخطئ: لنفترض أننا نعمل على تطوير موقع من خلال تحميل وصف الفيلم (لن نتعمق في واجهة برمجة تطبيقات moviedb ، ولكننا نأخذ فيلمًا معينًا كأساس). لدينا صفحتان:
الصفحة الرئيسية

معلومات عنا



تتوفر الروابط إلى كلتا الصفحتين في لوحة التنقل ، على سبيل المثال ، في الرأس. في الصفحة الرئيسية ("الصفحة الرئيسية") يوجد اتصال بالجزء الخلفي لتحميل معلومات حول الفيلم.

/src/Pages/HomePage.js
import React, { useState, useEffect } from 'react';

import { MOVIE_DB_GET } from '../config';

const HomePage = () => {
  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch(MOVIE_DB_GET);
        const result = await response.json();
        console.log(result, 'result')
      } catch (e) {
        console.error(e.message)
      }
    };

    //  get-     
    fetchData();
  }, []);

  return (
    <main>
      <h2> </h2>
    </main>
  )
};

export default HomePage;


/src/Pages/AboutPage.js

import React from 'react';

const AboutPage = () => {
  return (
    <main>
      <h2> </h2>
      <p>
                
      </p>
    </main>
  )
};

export default AboutPage;


لعرض المعلومات من خلال طلب ، من الضروري كتابة المعلومات إلى الدولة للعرض اللاحق:

/src/Pages/HomePage.js

import React, { useState, useEffect } from 'react';

import { MOVIE_DB_GET } from '../config';

const HomePage = () => {
  // movie - react-;
  // setMovie -   react-
  const [ movie, setMovie ] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch(MOVIE_DB_GET);
        const result = await response.json();
        console.log(result, 'result');
        setMovie(result);
      } catch (e) {
        console.error(e.message)
      }
    };

    //       
    fetchData();
  }, []);

  // descriptionMovie -  ,  view,         movie

  return (
    <main>
      <h2> </h2>
      <p> </p>

      {
        movie ? descriptionMovie() : false
      }
    </main>
  )
};

export default HomePage;


سنقوم بإعادة إنتاج الخطأ بالطريقة التالية - سننتقل من مسار إلى آخر ، أي كوننا في صفحة "من نحن" ، سننتقل إلى صفحة "الصفحة الرئيسية" ونعود فورًا إلى الصفحة "من نحن" و voila " لا يمكن أداء ... .. " .

والحقيقة هي أن الخادم لا يستجيب للطلبات على الفور ، حيث يتم استخدام التزامن للاستمرار في تشغيل الطلب بالتوازي مع المهام الضرورية. ولكن في حالة العودة السريعة إلى صفحة About Us ، فإن المكون Home غير مُركب ، مما يعني أنه سيتم إعادة تعيين حالة هذا المكون ، ولكن الطلب غير المتزامن سيستمر في تشغيل setMovie ، الذي لم يعد موجودًا وسيؤدي إلى حدوث خطأ. الحل الأفضل هو حظر استخدام تحديثات الحالة عند إلغاء تحميل المكون:

/src/Pages/HomePage.js

import React, { useState, useEffect } from 'react';

import { MOVIE_DB_GET } from '../config';

const HomePage = () => {
  // movie - react-;
  // setMovie -   react-
  const [ movie, setMovie ] = useState(null);

  useEffect(() => {
    let cleanupFunction = false;
    const fetchData = async () => {
      try {
        const response = await fetch(MOVIE_DB_GET);
        const result = await response.json();
        console.log(result, 'result')

        //     ,    
        if(!cleanupFunction) setMovie(result);
      } catch (e) {
        console.error(e.message)
      }
    };

    fetchData();

    //   useEffect
    return () => cleanupFunction = true;
  }, []);

  // descriptionMovie -  ,  view,         movie

  return (
    <main>
      <h2> </h2>
      <p> </p>

      {
        movie ? descriptionMovie() : false
      }
    </main>
  )
};

export default HomePage;


مجموع:


يمكن الاطلاع على جميع التعليمات البرمجية المصدر هنا: https://gitlab.com/ImaGadzhiev/react-cant-perform

All Articles