javascript - 无法使用 componentDidMount 从 API 获取数据:无法在未安装的组件上调用 setState(或 forceUpdate)
问题描述
我对 React 比较陌生。我用它来构建一个非常简单的应用程序。我正在尝试添加一个小功能,但遇到以下错误消息。我还不太明白根本原因。
Can't call setState (or forceUpdate) 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 the componentWillUnmount method.
这就是我想要做的。我的应用程序有一个提供各种 API 的后端服务器,它返回 JSON。我将 React 用作调用这些 API 并呈现它们的前端/客户端。
我有一个名为 Parent 组件MyReport
,用于componentDidMount
调用 API 来获取一些数据。然后在 render 方法中,我将数据传递给另一个名为MyReportViewer
. 该组件具有各种其他子组件,例如允许选择日期的日历、以表格格式显示数据的组件、将相同数据显示为图表的组件。
现在我正在尝试添加另一个名为的子组件MyReportSummary
,它将与由MyReportViewer
.
MyReportSummary
需要调用另一个 API 来获取一些数据。这是它的样子:
import React, { Component } from 'react';
class MyReportSummary extends Component {
constructor(props) {
super(props);
this.state = {
projectInfo: null,
isLoading: false,
error: null
};
}
componentDidMount() {
this.setState({ isLoading: true });
let projectInfoApi;
projectInfoApi = '/api/projects/' + this.props.projectId;
fetch(projectInfoApi)
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error('Encountered problem fetching project info')
}
})
.then(data => this.setState({
projectInfo: data
}))
.catch(fetchError => this.setState({
isLoading: false,
error: fetchError
}));
}
componentWillUnmount() {
// this.setState({
// projectInfo: null
// });
}
render() {
const { isLoading, error } = this.state;
if (error) {
return <p>{error.message}</p>
}
if (isLoading) {
return <p>Loading...</p>
}
return (
<div className="myReportSummary">
Summary of Project name: {projectInfo.name}
Number of events: {this.props.data.length}
</div>
);
}
}
export default MyReportSummary;
我已经读过我需要用来componentWillUnmount
重置所有内容,但我不确定我到底需要在这里重置什么以及为什么在这种情况下我需要这样做,因为我不认为我正在尝试更改组件在它已经加载或渲染之后。
解决方案
该警告表明您的组件在您有机会处理获取的响应之前已被卸载。
您可以在名为 eg 的状态之外保留组件上的属性,isMounted
并将其设置为false
incomponentWillUnmount
并检查是否是true
您的 fetch 完成的时间:
例子
class MyReportSummary extends Component {
mounted = true;
state = {
projectInfo: null,
isLoading: true,
error: null
};
componentDidMount() {
fetch(`/api/projects/${this.props.projectId}`)
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error("Encountered problem fetching project info");
}
})
.then(data => {
if (this.mounted) {
this.setState({
projectInfo: data
});
}
})
.catch(fetchError => {
if (this.mounted) {
this.setState({
isLoading: false,
error: fetchError
});
}
});
}
componentWillUnmount() {
this.mounted = false;
}
render() {
const { isLoading, error, projectInfo } = this.state;
if (error) {
return <p>{error.message}</p>;
}
if (isLoading) {
return <p>Loading...</p>;
}
return (
<div className="myReportSummary">
Summary of Project name: {projectInfo.name}
Number of events: {this.props.data.length}
</div>
);
}
}
推荐阅读
- apache-spark - PySpark 如何从 Dataframe 架构的 StructType 对象中解析和获取字段名称
- node.js - 如何将多个 JSON 对象插入到模式的一个属性中?
- .net - 登录凭证与公共 IP 的映射
- odoo - Odoo:选择树视图项目应链接到特殊视图
- html - 一张图片在 prestashop 中隐藏了我的段落
- jmeter - 1 用户和 100 用户的加载时间差异太大
- python - 我们如何根据颜色标记散点图的图例
- python - 恢复传递给 multiprocessing.Process 的函数返回值的最快方法
- angular - 在 Typescript Angular 2 中加入数组
- configuration - Azure 边缘部署和配置