Promise를 실행하면 해결되기까지 몇 초가 걸릴 수 있으며 그 때까지 사용자가 앱의 다른 위치로 이동했을 수 있습니다. 따라서 Promise resolves 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;
}
옵션 B : 또는 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