reactjs - reactjs组件错误与卸载
问题描述
从 reactjs 开始,我有一个我无法解决的问题。我尝试了很多来自互联网的示例,但我找不到编写此代码的正确方法。我为用户、公司和其他事物提供了更多这样的组件,但总的来说我得到了:
警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。
const mounted = useRef(true);
useEffect(() => {
socket.on('visiotrsnumber', (data) => {
if (mounted.current === true) setVisitorsNumber(data)
})
socket.on('loggedlist', (data) => {
if (mounted.current === true) setLoggedList(data)
})
}, []);
const fetchUsers = async () => {
try {
const responseData = await sendRequest(
'http://localhost:5000/api/users?page=1'
);
if (mounted.current === true){
setLoadedUsers(responseData.pageOfItems);
setTotalArticles(responseData.pager.totalItems);
setPage(responseData.pager.currentPage);
}
} catch (err) {}
};
const fetchUsersSearch = async () => {
try {
const responseData = await sendRequest(
`http://localhost:5000/api/users/search?search=${encodeURI(searchTerm)}&page=1`
);
if (mounted.current === true){
setLoadedUsers(responseData.pageOfItems);
setTotalArticles(responseData.pager.totalItems);
setPage(responseData.pager.currentPage);
}
} catch (err) {}
};
useEffect(() => {
!searchTerm ? fetchUsers() : fetchUsersSearch()
return () => {
mounted.current=false;
}
},[searchTerm, sendRequest]);
如果有人有一些例子,我应该如何正确地写这个?
解决方案
你有两个选择。要么使用一个组件范围的标志,要么为每个useEffect
带有清理回调的钩子使用一个标志。这是两个选项的草图:
- 组件宽标志
const mounted = useRef(false);
useEffect(() => {
mounted.current = true;
return () => mounted.current = false;
}, []);
// ...and usage example...
const fetchUsers = async () => {
try {
const responseData = await sendRequest('http://localhost:5000/api/users');
if (mounted.current) {
setLoadedUsers(responseData.pageOfItems);
}
} catch (error) {}
};
- 每个
useEffect
带有清理回调的钩子一个标志
useEffect(() => {
socket.on('visitorsnumber', setVisitorsNumber);
socket.on('loggedlist', setLoggedList);
return () => {
socket.off('visitorsnumber', setVisitorsNumber);
socket.off('loggedlist', setLoggedList);
};
}, []);
const fetchUsers = async (token) => {
try {
const responseData = await sendRequest('http://localhost:5000/api/users');
if (token.current) {
setLoadedUsers(responseData.pageOfItems);
}
} catch (error) {}
};
useEffect(() => {
const token = { current: true };
if (searchTerm)
fetchUsersSearch(token);
else
fetchUsers(token);
return () => token.current = false;
}, [searchTerm, sendRequest]);
我个人认为第二种方法更清洁。它还有一个额外的好处是可以防止过时的响应覆盖更新的结果。
推荐阅读
- arrays - 有没有更好的方法从这个 JSON 中提取值?
- r - 比较同一组中的列
- vb.net - 是否可以使用 VB.Net 通过代码访问 IME 窗口选项?
- google-cloud-platform - apigeex 是否提供不同云提供商的托管服务
- javascript - 比较 2 个对象数组检查匹配的值
- mysql - MySQL - 基于连接的 JOIN 更新父表
- java - 在 Spring-Boot-Web / Tomcat 中有条件地禁用 JSESSIONID
- c - 打印时 C 程序中的意外输出
- linux - 2 powermta 服务上的警告错误
- php - 如何使用 ajax 在 CodeIgniter 的自动完成中选择多个值