【发布时间】:2021-03-09 20:13:43
【问题描述】:
我正在开发一个使用 自定义挂钩 useRequest 从服务器获取数据的项目。
实现是
const useRequest = ({ url }) => {
const [isLoading, setIsLoading] = React.useState(true);
const [error, setError] = React.useState(null);
const [apiData, setApiData] = React.useState({});
React.useEffect(() => {
const abortController = new AbortController();
fetch(url, {
headers: headers,
signal: abortController.signal,
})
.then((res) => res.json())
.then((data) => {
setIsLoading(false);
if (data.status_message) {
throw Error(data.status_message);
}
setApiData(data);
})
.catch((err) => {
setError(err);
setIsLoading(false);
});
return function cleanup() {
abortController.abort();
};
}, [url]);
return { isLoading, apiData, error };
};
export default useRequest;
我不知道为什么,但有时它会引发内存泄漏错误。有人可以帮忙解释为什么会这样吗?
我使用 useRequest 钩子的组件:
1) ItemInfo 组件-
function Item() {
const { id } = useParams();
const { path } = useRouteMatch();
const type = path.split("/")[1];
const { isLoading, apiData, error } = useRequest({
url: request.getItemData(id, type),
});
if (error) return <NotFound error={error} />;
if (isLoading) return <Loader />;
const RowComp = withRow(Row);
return (
<div className="itemInfo">
{apiData && (
<>
<Banner data={apiData} />
<div className="itemInfo__wrapper">
<div className="itemInfo__overview">
<h2>Overview</h2>
<p>{apiData.overview}</p>
</div>
<Details details={apiData} />
<RowComp title="Cast" url={request.getCast(type, id)} />
{type === "movie" && apiData.belongs_to_collection && (
<RowComp
url={request.getCollection(apiData.belongs_to_collection.id)}
title="Collections"
/>
)}
{type === "tv" && apiData.seasons && (
<Row results={apiData.seasons} title="Seasons" />
)}
<RowComp
url={request.getRecommendations(id, type)}
title="Recommendations"
/>
</div>
</>
)}
</div>
);
}
export default Item;
2) HOC
function withRow(WrappedComponent) {
const HOC = ({ url, title }) => {
const { isLoading, apiData } = useRequest({ url });
const results = apiData.results || apiData.parts || apiData.cast;
return (
<>
{isLoading && <Loader />}
{results && <WrappedComponent results={results} title={title} />}
</>
);
};
HOC.propTypes = {
url: PropTypes.string,
title: PropTypes.string,
};
return HOC;
}
HOC 组件主要记录错误,但有时 ItemInfo 组件也会记录 Memory Leak 错误 提前致谢。
【问题讨论】:
-
我认为如果请求被取消,
.catch处理程序调用setError,这可能发生在组件已经卸载之后(因为取消发生在卸载时)。您可以在.catch中添加日志来检查吗? -
我确实发现了错误。这是日志
DOMException: The user aborted a request.但是在这个日志之前,有内存泄漏错误。 -
咦,那日志是从哪里来的?
-
.catch块,我添加了一个console.log。 -
啊,好的,您是在
setError之前还是之后添加日志?那么这可能是原因吗?
标签: javascript reactjs memory-leaks react-hooks