我有一个带有3个选项卡的react组件,每个选项卡都包含一个数据表,该数据表将根据活动选项卡填充API调用结果。 因此,每次都会有一个参数与API调用一起传递,并相应地显示数据。
这很好用,当我切换选项卡时,我正在获取数据,但是当我尝试从数据表中搜索然后单击另一个选项卡时,我收到错误信息-
无法在已卸载的组件上执行React状态更新。这是 无操作,但表示您的应用程序内存泄漏。修理, 取消所有订阅和异步任务 componentWillUnmount方法。
下面是我的示例代码:
component.jsx
import React, { Component } from "react";
import axios from "axios";
class Details extends Component {
constructor() {
super();
this.state = {
data: [],
flag: 0
};
}
componentDidMount() {
const params = new FormData();
params.append("status", "upcoming");
axios.post("details/", params).then(res => {
if (res.data.result === 1) {
this.setState({ data: res.data.data, flag: 1 });
}
});
}
handleClick = event => {
const params = new FormData();
params.append("status", event.target.getAttribute("data-value"));
axios.post("details/", params).then(res => {
if (res.data.result === 1) {
this.setState({ data: res.data.data, flag: 1 });
}
});
};
render() {
return (
<div className="col-md-9 col-sm-9 col-xs-12">
<div className="right_panel">
<h2>Listing</h2>
<div className="responsive-tabs text-center ">
<ul className="nav nav-tabs" role="tablist">
<li role="presentation" className="active">
<a
href="#Upcoming"
data-value="upcoming"
onClick={this.handleClick}
aria-controls="Upcoming"
role="tab"
data-toggle="tab"
>
Upcoming
</a>
</li>
<li role="presentation" className="">
<a
href="#Current"
data-value="active"
onClick={this.handleClick}
aria-controls="Current"
role="tab"
data-toggle="tab"
>
Current
</a>
</li>
<li role="presentation" className="">
<a
href="#past"
data-value="past"
onClick={this.handleClick}
aria-controls="past"
role="tab"
data-toggle="tab"
>
Past
</a>
</li>
</ul>
<div
id="tabs-content"
className="tab-content panel-group table-responsive"
>
<div className="panel-heading" role="tab" id="heading2">
<a
href="#Upcoming"
className="text-left collapsed textuppercase"
role="button"
data-toggle="collapse"
data-parent="tabs-content"
aria-expanded="true"
aria-controls="Upcoming"
>
<i className="fas fa-list-ul" /> Upcoming
<i className="fas fa-chevron-down pull-right" />
</a>
</div>
<div
id="Upcoming"
role="tabpanel"
className="tab-pane active panel-collapse collapse in"
aria-labelledby="heading2"
>
<table
id="first_Datatable"
className="display"
style={{ width: "100%" }}
>
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Open</th>
<th>Close</th>
<th>Listed</th>
<th>Price</th>
<th>Size</th>
</tr>
</thead>
{this.state.flag === 1 ? (
<tbody>
{this.state.data.map(d => (
<tr key={d.ipo_details_id}>
<td className="text-center">{d.ipo_details_id}</td>
<td>
<a href="#" title="">
{d.name}
</a>
</td>
<td>{d.open_date}</td>
<td>{d.close_date}</td>
<td>{d.size}</td>
<td>{d.listing}</td>
<td>{d.price}</td>
</tr>
))}
</tbody>
) : null}
</table>
</div>
<div className="panel-heading" role="tab" id="heading3">
<a
href="#Current"
className="collapsed text-left textuppercase"
role="button"
data-toggle="collapse"
data-parent="tabs-content"
aria-expanded="true"
aria-controls="Current"
>
<i className="fas fa-list-ul" /> Current{" "}
<i className="fas fa-chevron-down pull-right" />
</a>
</div>
<div
id="Current"
role="tabpanel"
className="tab-pane panel-collapse collapse"
aria-labelledby="heading3"
>
<table
id="second_Datatable"
className="display"
style={{ width: "100%" }}
>
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Open</th>
<th>Close</th>
<th>Listed</th>
<th>Price</th>
<th>Size</th>
</tr>
</thead>
{this.state.flag === 1 ? (
<tbody>
{this.state.data.map(d => (
<tr key={d.ipo_details_id}>
<td className="text-center">{d.ipo_details_id}</td>
<td>
<a href="#" title="">
{d.name}
</a>
</td>
<td>{d.open_date}</td>
<td>{d.close_date}</td>
<td>{d.size}</td>
<td>{d.listing}</td>
<td>{d.price}</td>
</tr>
))}
</tbody>
) : null}
</table>
</div>
<div className="panel-heading" role="tab" id="heading3">
<a
href="#past"
className="collapsed text-left textuppercase"
role="button"
data-toggle="collapse"
data-parent="tabs-content"
aria-expanded="true"
aria-controls="past"
>
{" "}
<i className="fas fa-list-ul" /> Past{" "}
<i className="fas fa-chevron-down pull-right" />
</a>
</div>
<div
id="past"
role="tabpanel"
className="tab-pane panel-collapse collapse"
aria-labelledby="heading3"
>
<table
id="third_Datatable"
className="display"
style={{ width: "100%" }}
>
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Open</th>
<th>Close</th>
<th>Listed</th>
<th>Price</th>
<th>Size</th>
</tr>
</thead>
{this.state.flag === 1 ? (
<tbody>
{this.state.data.map(d => (
<tr key={d.ipo_details_id}>
<td className="text-center">{d.ipo_details_id}</td>
<td>
<a href="#" title="">
{d.name}
</a>
</td>
<td>{d.open_date}</td>
<td>{d.close_date}</td>
<td>{d.size}</td>
<td>{d.listing}</td>
<td>{d.price}</td>
</tr>
))}
</tbody>
) : null}
</table>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Details;
我尝试使用componentWillUnmount更新,但没有解决。
我正在index.html中初始化数据表。
那么这可能是解决方案。
答案 0 :(得分:1)
这里的问题似乎是您有一个数据模型,该数据模型正以组件状态存储,但是该组件不会停留很长时间。因此,您有几种选择:
选择哪种选项取决于您要完成的工作。
答案 1 :(得分:0)
问题似乎出在您在componentDidMount中发送的POST请求中。
componentDidMount() {
const params = new FormData();
params.append("status", "upcoming");
axios.post("details/", params).then(res => {
if (res.data.result === 1) {
this.setState({ data: res.data.data, flag: 1 });
}
});
}
如果您在状态更新之前用以下内容修改if
语句怎么办?
if (res.data.result === 1 && this.state) {
这样,它将仅在this.state
存在的情况下尝试更新状态吗?简单而优雅。
让我知道这是否无效!