Saat Anda mengaktifkan Promise, mungkin perlu waktu beberapa detik sebelum dijawab dan pada saat itu pengguna mungkin sudah menavigasi ke tempat lain di aplikasi Anda. Jadi, ketika Promise resolves setState
dijalankan pada komponen yang tidak di-unmount dan Anda mendapatkan kesalahan - seperti dalam kasus Anda. Ini juga dapat menyebabkan kebocoran memori.
Itulah mengapa yang terbaik adalah memindahkan beberapa logika asinkron Anda dari komponen.
Jika tidak, Anda harus membatalkan Janji Anda . Atau - sebagai teknik pilihan terakhir (ini adalah antipattern) - Anda dapat menyimpan variabel untuk memeriksa apakah komponen masih terpasang:
componentDidMount(){
this.mounted = true;
this.props.fetchData().then((response) => {
if(this.mounted) {
this.setState({ data: response })
}
})
}
componentWillUnmount(){
this.mounted = false;
}
Saya akan menekankannya lagi - ini adalah antipattern tetapi mungkin cukup dalam kasus Anda (seperti yang mereka lakukan dengan Formik
implementasi).
Diskusi serupa di GitHub
EDIT:
Ini mungkin bagaimana saya menyelesaikan masalah yang sama (tidak memiliki apa-apa selain Bereaksi) dengan Hooks :
OPSI 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;
}
OPSI B: Alternatifnya useRef
yang berperilaku seperti properti statis kelas yang berarti tidak membuat perenderan komponen saat nilainya berubah:
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;
}
Contoh: https://codesandbox.io/s/86n1wq2z8