Javascript 我得到错误:Can';即使我创建了清理,也不能对未安装的组件执行React状态更新
我的应用程序上的一个错误一直困扰着我Javascript 我得到错误:Can';即使我创建了清理,也不能对未安装的组件执行React状态更新,javascript,node.js,reactjs,Javascript,Node.js,Reactjs,我的应用程序上的一个错误一直困扰着我 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function. 我
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
我确实在我的上下文中声明了useEffect,这样我就可以为我的应用程序存储和获取实时数据
这是我在上下文中的代码
const FetchProvider = ({ children }) => {
const [userList, setUserList] = useState([]);
const [teamList, setTeamList] = useState([]);
const authContext = useContext(AuthContext);
const authAxios = axios.create({
baseURL: process.env.REACT_APP_API_URL,
});
useEffect(() => {
let isCancelled = false;
if (
authContext.isAuthenticated &&
authContext.authState.userInfo !== null
) {
const getUsers = async () => {
try {
const users = await authAxios.get('/admin/get-all-users');
if (!isCancelled) {
setUserList(users.data);
}
} catch (error) {
if (!isCancelled) {
console.log(error);
}
}
};
const getTeams = async () => {
try {
const teams = await authAxios.get('/get-all-teams');
if (!isCancelled) {
setTeamList(teams.data);
}
} catch (error) {
if (!isCancelled) {
console.log(error);
}
}
};
getUsers();
getTeams();
}
return () => {
isCancelled = true;
};
}, [authAxios, authContext]);
return (
<Provider
value={{
authAxios,
userList,
setUserList,
teamList,
setTeamList,
}}
>
{children}
</Provider>
);
};
我已经尝试了许多互联网提供的方法来解决这个问题,但不幸的是,它并没有解决我的问题
我在UsersTable.jsx和TeamTables.jsx中确实有useffect
这是我在UsersTable.jsx中的代码
useEffect(() => {
let isCancelled = false;
const getUsers = async () => {
try {
const users = await fetchContext.authAxios.get('/admin/get-all-users');
setIsLoaded(true);
if (isLoaded === true) {
if (!isCancelled) {
fetchContext.setUserList(users.data);
}
}
return () => {
isCancelled = true;
};
} catch (error) {
if (!isCancelled) {
console.log(error);
}
}
};
getUsers();
return () => {
isCancelled = true;
};
}, [fetchContext, isLoaded]);
useEffect(() => {
let isCancelled = false;
const getTeams = async () => {
try {
const teams = await fetchContext.authAxios.get('get-all-teams');
setIsLoaded(true);
if (isLoaded === true) {
if (!isCancelled) {
fetchContext.setTeamList(teams.data);
}
}
} catch (error) {
if (!isCancelled) {
console.log(error);
}
}
};
getTeams();
return () => {
isCancelled = true;
};
}, [fetchContext, isLoaded]);
这是我的TeamTable.jsx中的useEffect代码
useEffect(() => {
let isCancelled = false;
const getUsers = async () => {
try {
const users = await fetchContext.authAxios.get('/admin/get-all-users');
setIsLoaded(true);
if (isLoaded === true) {
if (!isCancelled) {
fetchContext.setUserList(users.data);
}
}
return () => {
isCancelled = true;
};
} catch (error) {
if (!isCancelled) {
console.log(error);
}
}
};
getUsers();
return () => {
isCancelled = true;
};
}, [fetchContext, isLoaded]);
useEffect(() => {
let isCancelled = false;
const getTeams = async () => {
try {
const teams = await fetchContext.authAxios.get('get-all-teams');
setIsLoaded(true);
if (isLoaded === true) {
if (!isCancelled) {
fetchContext.setTeamList(teams.data);
}
}
} catch (error) {
if (!isCancelled) {
console.log(error);
}
}
};
getTeams();
return () => {
isCancelled = true;
};
}, [fetchContext, isLoaded]);
isLoaded被用作AJAX那么,您可以使用React推荐的方法来解决这个问题。您所需要做的就是将api调用包装在makeCancelable方法中,并在组件卸载时取消它们 参考: 要做到这一点,请创建
const makeCancelable = (promise) => {
let isCancelled = false;
const wrappedPromise = new Promise((resolve, reject) => {
promise.then(
val => isCancelled ? reject({isCanceled: true}) : resolve(val),
error => isCancelled ? reject({isCanceled: true}) : reject(error)
);
});
return {
promise: wrappedPromise,
cancel() {
isCancelled = true;
},
};
};
在useffect
let fetchTeamsRequest = null;
并更新了useffect
函数,如下所示
useEffect(() => {
const getTeams = async () => {
if (fetchTeamsRequest) {
try {
await fetchTeamsRequest.promise;
return;
} catch (error) {
return;
}
}
fetchTeamsRequest = makeCancellable(fetchContext.authAxios.get('get-all-teams'));
try {
const teams = await fetchTeamsRequest.promise;
fetchTeamsRequest = null;
setIsLoaded(true);
if (isLoaded === true) {
if (!fetchTeamsRequest.isCancelled) {
fetchContext.setTeamList(teams.data);
}
}
} catch (error) {
if (!fetchTeamsRequest.isCancelled) {
fetchTeamsRequest = null;
console.log(error);
}
}
};
getTeams();
return () => {
if (fetchTeamsRequest) {
fetchTeamsRequest.cancel();
}
};
}, [fetchContext, isLoaded]);
那么,您可以使用React建议的方法来解决此问题。您所需要做的就是将api调用包装在makeCancelable方法中,并在组件卸载时取消它们 参考: 要做到这一点,请创建
const makeCancelable = (promise) => {
let isCancelled = false;
const wrappedPromise = new Promise((resolve, reject) => {
promise.then(
val => isCancelled ? reject({isCanceled: true}) : resolve(val),
error => isCancelled ? reject({isCanceled: true}) : reject(error)
);
});
return {
promise: wrappedPromise,
cancel() {
isCancelled = true;
},
};
};
在useffect
let fetchTeamsRequest = null;
并更新了useffect
函数,如下所示
useEffect(() => {
const getTeams = async () => {
if (fetchTeamsRequest) {
try {
await fetchTeamsRequest.promise;
return;
} catch (error) {
return;
}
}
fetchTeamsRequest = makeCancellable(fetchContext.authAxios.get('get-all-teams'));
try {
const teams = await fetchTeamsRequest.promise;
fetchTeamsRequest = null;
setIsLoaded(true);
if (isLoaded === true) {
if (!fetchTeamsRequest.isCancelled) {
fetchContext.setTeamList(teams.data);
}
}
} catch (error) {
if (!fetchTeamsRequest.isCancelled) {
fetchTeamsRequest = null;
console.log(error);
}
}
};
getTeams();
return () => {
if (fetchTeamsRequest) {
fetchTeamsRequest.cancel();
}
};
}, [fetchContext, isLoaded]);
那在我的Login.jsx中没有useEffect的呢?我应该实现相同的代码吗?您应该在发出异步请求的任何地方使用makeCancelable。不幸的是,这在我的Login.jsx文件上不起作用。您在Login.jsx上遇到了什么错误?与我遇到的错误相同;那在我的Login.jsx中没有useEffect的呢?我应该实现相同的代码吗?您应该在发出异步请求的任何地方使用makeCancelable。不幸的是,这在我的Login.jsx文件上不起作用。您在Login.jsx上遇到了什么错误?与我遇到的错误相同;