繁体   English   中英

无法对未安装的组件执行 React state 更新。(UseEffect)(Context API)(REACT.js)

[英]Can't perform a React state update on an unmounted component.(UseEffect)(Context API)(REACT.js)

所以我收到这个警告:-

*Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
    in Products (created by Context.Consumer)*

好吧,当我重新路由到产品编辑组件时,它发生在产品组件中。 Products 组件用于列出所有产品,product edit 用于编辑产品详细信息,这两个组件都使用 useContext 连接到相同的上下文 API。 我的上下文 API 提供商看起来像这样

*import React, { useState , createContext , useEffect} from 'react';
import firebase from "../firebase";

export const ProdContext = createContext();

const ProdContextProvider = props => {
    const [products , setproducts]= useState([])
    const [loading , setloading] = useState(true)
    const [subcribe , setsubcribe] = useState(false)


    const unsub =()=>{
        setsubcribe(false);
        console.log("unsubcribe--"+subcribe)
      }
      const sub =()=>{
        setsubcribe(true);
        console.log("subcribe--"+subcribe)
      }

    useEffect(() => {
        let mounted = true;
        setloading(true)
        async function fetchData() {
        setloading(true);
        await firebase.firestore()
        .collection("products")
        .onSnapshot((snapshot)=>{
            
            const data = snapshot.docs.map((doc)=>(
                {
                    id : doc.id,
                    ...doc.data()
                }
            ))
            console.log("b4 if--"+subcribe)
            if(subcribe){
                console.log("in if--"+subcribe)
            setproducts(data)
            setloading(false)
            }
        })
        }
        fetchData();
        return () => mounted = false;
    }, [subcribe])
    
    console.log("after getting bottom"+subcribe)
    return (
        <ProdContext.Provider value={{subcribe:subcribe,prodloading:loading, products: products, loading:loading , sub:sub , unsub:unsub}}>
            {props.children}
        </ProdContext.Provider>
    );
}
export default ProdContextProvider;*

我的产品组件如下所示:

export default function Products(props){
    const {products , loading ,sub , unsub,subcribe}= useContext(ProdContext)
    const [selectid, setselectid] = useState("")
    const [ShowLoading, setShowLoading] = useState(true);
    const [showAlert2, setShowAlert2] = useState(false);
    const [redirect , setredirect] = useState(false)
    const [value, setValue] = useState(null);
    const [inputValue, setInputValue] = useState('');

    
 useEffect(() => {
     sub();
     console.log("product mound--"+subcribe)
 }, [])

 useEffect(() => {
    return () => {
        console.log("product unsub--"+subcribe)
        unsub();
        console.log("product unmound--"+subcribe)
    };
  }, []);

      if (redirect) {
        return <Redirect push to={{
            pathname: `/products/${selectid}`,  
        }} />;
      }
    return ( .........)}

产品编辑组件:

const Productedit = (props) => {

const {products,loading , subcribe} = useContext(ProdContext);
const { sub,unsub } = useContext(ProdContext);
  const [formData, setformData] = useState({});
  const {category} = useContext(CatContext)
  const [showLoading, setShowLoading] = useState(false);
  const [mainurl, setmainurl] = useState(null);
  const [imggal, setimggal] = useState([]);
  const [situation , setsituation] = useState("")
  const [redirect , setredirect] = useState(false)
  const [showAlert, setShowAlert] = useState(false);
  const [msg, setmsg] = useState(true);

 useEffect(() => {
     sub();
     console.log("productedit mound--"+subcribe)
     return () => unsub();
 }, [])
...........

好吧,我认为问题是产品组件即使在卸载时仍然订阅了 getproduct provider 但我无法解决任何人都可以提供帮助的问题

错误消息详细信息和控制台日志

该问题与 Firestore 无关,而这似乎是 React 的常见问题。

  • 如果组件尚未安装,我们只需要在回调中更新 state 即可。

  • 最好在更新 state 之前通过在异步 function 中添加一个 if 块来检查

    if(mounted) {// Code inside the async tasks}

有关此警告的更多信息,请参阅此处 [1]。

[1] https://www.debuggr.io/react-update-unmounted-component/#state-updates

(这应该是评论,因为我没有足够的声誉,因此作为答案发布)

希望我能正确理解问题并且建议有帮助!

你没有使用mounted除了初始化它,你不应该更新你的反应 state 如果你的组件被卸载。 在 API 请求成功后,您应该在回调中执行此操作:

if(mounted){
   // your state update goes here
}

但这不对,你应该做的是在组件卸载时取消你的 API 请求,我对使用axios时的请求取消知之甚少。 您应该在 web 中搜索有关 API 请求取消的信息 firebase 或您正在使用的任何内容,因为如果您没有更新您的反应 state 如果组件卸载,那么 API 请求仍然会继续在后台运行,这是主要问题,这就是反应抛出此问题的原因警告。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM