嗨,我创建了一个React钩子来处理Axios请求。我遇到的问题是,为了防止内存泄漏,我无法成功地中止请求。当我在使用钩子的两个页面之间切换时,我会得到错误:
无法对未挂载的组件执行反应状态更新。这是一个非操作,但它表示您的应用程序中存在内存泄漏。若要修复,请取消useEffect清理函数中的所有订阅和异步任务。
useAxios钩子代码:
import { useState, useEffect } from "react";
import axios from "axios";
const useAxios = (url, method = "GET") => {
const [data, setData] = useState([]);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(false);
const [body, setBody] = useState(null);
useEffect(() => {
const controller = new AbortController();
const getData = async (body) => {
setLoading(true);
try {
const res = body
? await axios.post(url, body, {
signal: controller.signal,
})
: await axios.get(url, {
signal: controller.signal,
});
setData(res.data);
setError(null);
setLoading(false);
} catch (err) {
console.log(err.message);
setError(err.message);
setLoading(false);
}
};
if (method === "GET") {
getData();
} else if (method === "POST") {
getData(body);
}
return () => {
controller.abort();
};
}, [url, method, body]);
return { data, error, loading, setBody };
};
export default useAxios;发布于 2022-06-16 20:24:43
您的setError和setLoading在中止时都会触发。
因此,您需要在卸载回调中设置一个标志。然后,您可以基于此有条件地调用setError / setLoading。
useEffect(() => {
let aborting = false;
try {
....
} catch (err) {
console.log(err.message);
if (!aborting) {
setError(err.message);
setLoading(false);
}
}
....
return () => {
aborting = true;
controller.abort();
}
}, ...防止内存泄漏
只是一张纸条,这个伤口实际上不是一个记忆泄漏,它只是一个警告,它可能来自一个。例如:使用addEventListener而不使用removeEventListener。但是,在这两种情况下,您仍然希望防止setState出现在umounted组件上。
https://stackoverflow.com/questions/72651432
复制相似问题