首页 > 解决方案 > 如何修复:警告:无法对未安装的组件执行 React 状态更新

问题描述

我在 useEffect 之外有一个名为 getRelevates 的函数,问题是当我更改组件的状态以添加获得的信息时,控制台返回此错误:

警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。

这是我的组件的代码:

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

import './Start.css';

import CardProduct from '../CardProduct/CardProduct';
import { db } from '../../firebase';
import CardEstreno from '../CardEstreno/CardEstreno';

const Start = () => {
    const [productsRelevates, setProductsRelevates] = useState([]);
    const [productsEstreno, setProductsEstreno] = useState([]);

    const getRelevates = () => {
            db.collection('Products').onSnapshot((querySnapshot) => {
                const docs = [];
                const es = [];
                querySnapshot.forEach((doc) => {
                    if (doc.data().Relevancia === true) {
                        docs.push({ ...doc.data(), id: doc.id });
                    }

                    if (doc.data().Estreno === true) {
                        es.push({ ...doc.data(), id: doc.id });
                    }
                });
                setProductsRelevates(docs);
                setProductsEstreno(es);
            });
        };

    useEffect(() => {
        getRelevates();
    }, []);
    
    return <div className="recom">
                    {productsRelevates !== []
                        ? productsRelevates.map((doc) => {
                                return (
                                    <div key={doc.id}>
                                        <CardProduct product={doc} />
                                    </div>
                                );
                          })
                        : ''}
                </div>
}

标签: javascriptreactjs

解决方案


您必须使用返回函数清理 useEffect 中的侦听器。像这样的东西(未经测试):

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

import './Start.css';

import CardProduct from '../CardProduct/CardProduct';
import { db } from '../../firebase';
import CardEstreno from '../CardEstreno/CardEstreno';

const Start = () => {
    const [productsRelevates, setProductsRelevates] = useState([]);
    const [productsEstreno, setProductsEstreno] = useState([]);
     
      useEffect(() => {

        const onSnapshotHandler =  querySnapshot => {
          const docs = [];
          const es = [];
          querySnapshot.forEach((doc) => {
              if (doc.data().Relevancia === true) {
                  docs.push({ ...doc.data(), id: doc.id });
              }
    
              if (doc.data().Estreno === true) {
                  es.push({ ...doc.data(), id: doc.id });
              }
          });
          setProductsRelevates(docs);
          setProductsEstreno(es);
        };

        const unsubscribe = db.collection('Products').onSnapshot(onSnapshotHandler);

        return (() => unsubscribe());
        
    }, []);
    
    return <div className="recom">
                    {productsRelevates !== []
                        ? productsRelevates.map((doc) => {
                                return (
                                    <div key={doc.id}>
                                        <CardProduct product={doc} />
                                    </div>
                                );
                          })
                        : ''}
                </div>
}

推荐阅读