[英]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.