У меня есть компонент реакции с 3 вкладками, и каждая вкладка содержит таблицу данных, которая будет заполнена результатом вызова API на основе активной вкладки. Таким образом, каждый раз будет параметр, который я передаю с вызовом API и соответствующим образом отображаю данные.
Это отлично работает, я получаю данные, когда переключаюсь между вкладками, но когда я пытаюсь выполнить поиск в таблице данных, а затем нажимаю на другую вкладку, я получаю сообщение об ошибке:
Can't perform a React state update 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.
Ниже мой пример кода:
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.
Итак, какое может быть возможное решение для этого.
@Morgan Мой API разработан на Django, а база данных - PostgreSQL





Кажется, проблема связана с запросом POST, который вы отправляете в componentDidMount.
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 существует? Достаточно просто и элегантно.
Сообщите мне, если это не сработает!
С этим изменением моя таблица данных не работала, сортировка и поиск не работали. Затем я сделал три разных компонента для вкладок, после чего вызвал свой api в этих компонентах и назвал эти файлы в компоненте Details. Теперь все работает нормально
Я действительно рада, что ты это понял! Извините, я больше не помог. :)
Похоже, проблема здесь в том, что у вас есть модель данных, которая сохраняется в состоянии компонента, но этот компонент не задерживается надолго. Итак, у вас есть несколько вариантов:
Какой вариант вы выберете, зависит от того, чего вы хотите достичь.
Вы можете уточнить, что это за база данных и где находится код для нее?