在我的 React 组件中,我有一个 async
请求,它向我的 Redux 存储分派(dispatch)一个操作,该操作在 useEffect
Hook 中调用:
const loadFields = async () => {
setIsLoading(true);
try {
await dispatch(fieldsActions.fetchFields(user.client.id));
} catch (error) {
setHasError(true);
}
setIsLoading(false);
}
useEffect(() => { if(isOnline) { loadFields() } }, [dispatch, isOnline]);
该操作通过获取请求请求数据:
export const fetchFields = clientId => {
return async dispatch => {
try {
const response = await fetch(
Api.baseUrl + clientId + '/fields',
{ headers: { 'Apiauthorization': Api.token } }
);
if (!response.ok) {
throw new Error('Something went wrong!');
}
const resData = await response.json();
dispatch({ type: SET_FIELDS, payload: resData.data });
} catch (error) {
throw error;
}
}
};
export const setFields = fields => ({
type : SET_FIELDS,
payload : fields
});
当它在 React 应用程序中呈现时,会导致以下警告:
无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,取消 %s 中的所有订阅和异步任务。%s,一个 useEffect 清理函数
我相信这是因为 promise 没有“清理”功能。但我不确定把它放在哪里?我是否应该在 LoadFields()
中包含一些逻辑?还是必须在 useEffect
Hook 中完成?
最佳答案
这tutorial这将帮助您解决问题。
简单示例:使用 Promises
function BananaComponent() {
const [bananas, setBananas] = React.useState([])
React.useEffect(() => {
let isSubscribed = true
fetchBananas().then( bananas => {
if (isSubscribed) {
setBananas(bananas)
}
})
return () => isSubscribed = false
}, []);
return (
<ul>
{bananas.map(banana => <li>{banana}</li>)}
</ul>
)
}
简单示例:使用 async/await(不是最好的,但应该与匿名函数一起使用)
function BananaComponent() {
const [bananas, setBananas] = React.useState([])
React.useEffect(() => {
let isSubscribed = true
async () => {
const bananas = await fetchBananas();
if (isSubscribed) {
setBananas(bananas)
}
})();
return () => isSubscribed = false
}, []);
return (
<ul>
{bananas.map(banana => <li>{banana}</li>)}
</ul>
)
}
关于javascript - 如何取消异步 promise 中的订阅以避免 Reactjs 中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58166044/