जब आप एक वादा करते हैं, तो इसे हल होने से पहले कुछ सेकंड लग सकते हैं और उस समय तक उपयोगकर्ता आपके ऐप में किसी अन्य स्थान पर नेविगेट कर सकता है। इसलिए जब वादा हल किया setState
जाता है, तो यह अनमाउंट घटक पर निष्पादित होता है और आपको एक त्रुटि मिलती है - जैसे आपके मामले में। इससे मेमोरी लीक भी हो सकती है।
यही कारण है कि घटकों में से कुछ को अपने अतुल्यकालिक तर्क को स्थानांतरित करना सबसे अच्छा है।
अन्यथा, आपको किसी तरह अपना वादा रद्द करने की आवश्यकता होगी । वैकल्पिक रूप से - अंतिम उपाय की तकनीक के रूप में (यह एक एंटीपैटर्न है) - आप यह जाँचने के लिए एक चर रख सकते हैं कि क्या घटक अभी भी आरोहित है:
componentDidMount(){
this.mounted = true;
this.props.fetchData().then((response) => {
if(this.mounted) {
this.setState({ data: response })
}
})
}
componentWillUnmount(){
this.mounted = false;
}
मैं फिर से जोर दूंगा - यह एक एंटीपैटर्न है, लेकिन आपके मामले में पर्याप्त हो सकता है (ठीक उसी तरह जैसे उन्होंने Formik
कार्यान्वयन के साथ किया था)।
GitHub पर इसी तरह की चर्चा
संपादित करें:
यह शायद मैं हुक के साथ एक ही समस्या (प्रतिक्रिया के अलावा कुछ भी नहीं) को कैसे हल करूंगा :
विकल्प A:
import React, { useState, useEffect } from "react";
export default function Page() {
const value = usePromise("https://something.com/api/");
return (
<p>{value ? value : "fetching data..."}</p>
);
}
function usePromise(url) {
const [value, setState] = useState(null);
useEffect(() => {
let isMounted = true;
request.get(url)
.then(result => {
if (isMounted) {
setState(result);
}
});
return () => {
isMounted = false;
};
}, []);
return value;
}
विकल्प बी: वैकल्पिक रूप से useRef
जिसके साथ एक वर्ग की स्थिर संपत्ति की तरह व्यवहार किया जाता है, जिसका अर्थ है कि यह मूल्य परिवर्तन होने पर घटक रेंडर नहीं करता है:
function usePromise2(url) {
const isMounted = React.useRef(true)
const [value, setState] = useState(null);
useEffect(() => {
return () => {
isMounted.current = false;
};
}, []);
useEffect(() => {
request.get(url)
.then(result => {
if (isMounted.current) {
setState(result);
}
});
}, []);
return value;
}
function useIsMounted() {
const isMounted = React.useRef(true)
useEffect(() => {
return () => {
isMounted.current = false;
};
}, []);
return isMounted;
}
उदाहरण: https://codesandbox.io/s/86n1wq2z8