所以我收到此警告:-
*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)*
好吧,当我重新路由到“产品编辑”组件时,它出现在“产品”组件中! 产品组件用于列出所有产品,产品编辑用于编辑产品详细信息,并且这两个组件都使用useContext连接到相同的上下文API。 我的Context 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,但我无法解决任何人都可以提供帮助的问题
答案 0 :(得分:0)
该问题与Firestore无关,但这似乎是react的常见问题。
如果该组件尚未安装,我们就不需要更新回调中的状态。
最好在更新状态之前进行检查,方法是在异步函数中添加if块
if(mounted) {// Code inside the async tasks}
有关此警告的更多信息,请参见此处[1]。
[1] https://www.debuggr.io/react-update-unmounted-component/#state-updates
(这应该是一条评论,因为我没有足够的声誉,因此发布为答案)
希望我理解正确的问题,该建议会有所帮助!
答案 1 :(得分:0)
除了仅初始化 mounted
外,您没有使用它,如果卸载了组件,则不应更新您的反应状态。成功的API请求后,您应该在回调中执行此操作:
if(mounted){
// your state update goes here
}
但这不是正确的,您应该做的是在卸载组件时取消API请求,我不太了解使用 axios 时的请求取消。您应该在网络上搜索有关Firebase中API请求取消的信息,或者您正在使用的内容,因为如果组件卸载后您没有更新React状态,那么API请求仍然在后台运行,这是主要问题,这就是为什么React会抛出此错误警告。