Проблема здесь в том, что если мои новые данные извлекаются из моего бэкэнда (RestAPI), таблица данных не отображает новые данные, даже если я вызвал this.setState, и если я регистрирую новое состояние, извлеченные данные регистрируются в консоли. , но не отображается в моей таблице данных. Когда я жестко кодирую данные в конструкторах this.state = xxx, данные отображаются просто отлично. Итак, я думаю, что это должно быть связано с какой-то проблемой повторного рендеринга? Я отлаживал часами, но так и не смог найти проблему. Было бы очень здорово, если бы кто-нибудь мог помочь мне здесь :)
Я читал очень много статей и постов о том, как не перерисовывать и о жизненном цикле реактивных компонентов. В качестве дополнительной информации, когда я регистрирую состояние в методе рендеринга перед возвращаемыми значениями, оно сначала равно нулю (поскольку я инициализировал состояние), а после второго рендеринга данные находятся в this.state.rowData по желанию. Но я просто не могу понять, почему он не отображается в таблице данных.
constructor(props) {
super(props);
this.state = {
columnDefs: [{
headerName: "Dump Name", field: "dumpName", sortable: true, filter: true
}, {
headerName: "Type", field: "type", sortable: true, filter: true
}, {
headerName: "Size", field: "length", sortable: true, filter: true
}, {
headerName: "Different CAN-IDs", field: "canIdCount", sortable: true, filter: true
}, {
headerName: "Created At", field: "createdAt", sortable: true, filter: true
}],
rowData: null
}
}
componentDidMount = async () => {
let collectionData = [];
await getSniffs().then(function (sniffdata) {
sniffdata.map(async function (row) {
collectionData.push({
dumpName: row,
length: await getMessageCount(row).then(function (res) {
return res[0].all;
}),
canIdCount: await getIdCountDistinct(row).then(function (res) {
return res[0].count;
}),
createdAt: await getFirstTimestamp(row).then(function (res) {
return res[0].firstTimestamp;
}),
type: "CAN Message"
});
});
}).then(() => this.setState({
rowData: collectionData
}));
};
render() {
console.info(this.state);
return (
<div
className = "ag-theme-material"
style = {{
height: '500px',
width: '1000px' }}
>
<AgGridReact
// onRowClicked = {this.onRowClicked.bind(this)}
columnDefs = {this.state.columnDefs}
rowData = {this.state.rowData}>
</AgGridReact>
</div>
// : <Loading/>;
)}
}
export default withRouter(SniffOverviewDatatable);
Таблица данных просто показывает: Нет строки для отображения. Сначала я думаю, что это правильный результат, но он должен обновиться и показать мои полученные данные. Журналы отображают именно нужные данные и структуру массива.
Спасибо за ваше время, и я действительно надеюсь получить некоторые подсказки :)
Обновлено: Эй, эй, я только что переписал функцию componentDidMount, но, боюсь, это ничего не изменило. Данные регистрируются, но таблица не обновляется:/
Вот новый код функции (используется async/await):
componentDidMount = async () => {
let rowData = [];
try {
const sniffs = await getSniffs();
sniffs.map(async function (row) {
const msgCount = await getMessageCount(row);
const idCount = await getIdCountDistinct(row);
const firstTimestamp = await getFirstTimestamp(row);
rowData.push({
dumpName: row,
length: msgCount[0].all,
canIdCount: idCount[0].count,
createdAt: firstTimestamp[0].firstTimestamp,
type: "CAN Message"
});
});
} catch (e) {
console.info(e);
}
this.setState({
rowData
});
};
Вы уже пробовали использовать setState с функцией обратного вызова и какой-нибудь библиотекой неизменяемости, такой как immutability-helper? Это приведет к такому коду:
import update from 'immutability-helper';
...
this.setState(prevState => update(prevState, {rowData: {$set: collectionData}});
...
Привет, я просто хотел дать свой собственный ответ, если кто-нибудь посмотрит на этот вопрос:
componentDidMount = async () => {
let fetched = await getSniffs();
let rowData = [];
for (const row of fetched.data) {
const msgCount = await getMessageCount(row);
const idCount = await getIdCountDistinct(row);
const firstTimestamp = await getFirstTimestamp(row);
rowData.push({
dumpName: row,
length: msgCount.data[0].all,
canIdCount: idCount.data[0].count,
createdAt: new Date(firstTimestamp.data[0].firstTimestamp),
type: "CAN Message"
});
}
this.setState({
rowData
});
};
Теперь это работает отлично :) Я также перенес этот метод на один компонент выше, поэтому datatable просто получает свои данные через реквизит, а не через состояние. Спасибо и закрыто!
Эй :) спасибо за совет. Я проверил это и использовал этот фрагмент кода:
this.setState(prevState => update(prevState, {rowData: {$set: rowData}}));
Боюсь, я получил тот же результат, что и раньше: ibb.co/S5Rj8Pq -> Console.log this.state.rowData в функции рендеринга.