每次当onClick
执行时我收到一条有关内存泄漏的警告消息。如何取消订阅组件上下文.消费者在我的功能组件中useEffect
hook?
我没有找到如何取消订阅 AppContext 的方法。AppContext.unsubsribe()
不工作。
import React, {useState, useContext} from 'react';
import {withRouter} from 'react-router-dom';
import axios from 'axios';
import {AppContext} from "../context/AppContext";
const LoginPage = (props) => {
const [name, setName] = useContext(AppContext);
const [isLoading, setIsLoading] = useState(false);
const onClick = () => {
setIsLoading(true);
axios.post('/get-name')
.then(resp => {
setName(resp);
setIsLoading(false);
props.history.push('/');
})
.catch(err => console.log(err))
.finally(() => setIsLoading(false));
};
return (
<div>
<button onClick={onClick}></button>
</div>
);
};
export default withRouter(LoginPage);
浏览器控制台中的错误消息:
警告:无法在已卸载的设备上执行 React 状态更新
成分。这是一个空操作,但它表明您的内存泄漏
应用。要修复此问题,请取消所有订阅和异步任务
在 useEffect 清理函数中。
在 UserPage 中(由 Context.Consumer 创建)
在路线中(由 withRouter(UserPage) 创建)
在 withRouter(LoginPage) 中(由 Context.Consumer 创建)
在路线中(由 UserRoute 创建)
您的问题是 axios 返回一个承诺,因此当安装组件时,它会执行axios.post(...)
单击时。当它然后卸载时(虽然承诺仍然是“未完成的”),setState
of its finally
将在组件卸载后执行。
您可以使用简单的方法检查组件是否已安装:
import React, {useState, useContext, useEffect} from 'react';
import {withRouter} from 'react-router-dom';
import axios from 'axios';
import {AppContext} from "../context/AppContext";
const LoginPage = (props) => {
const [name, setName] = useContext(AppContext);
const [isLoading, setIsLoading] = useState(false);
const isMounted = useRef(null);
useEffect(() => {
// executed when component mounted
isMounted.current = true;
return () => {
// executed when unmount
isMounted.current = false;
}
}, []);
const onClick = () => {
setIsLoading(true);
axios.post('/get-name')
.then(resp => {
setName(resp);
setIsLoading(false);
props.history.push('/');
})
.catch(err => console.log(err))
.finally(() => {
if (isMounted.current) {
setIsLoading(false)
}
});
};
return (
<div>
<button onClick={onClick}></button>
</div>
);
};
export default withRouter(LoginPage);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)