Асинхронная выборка данных, не перерисовывающих данные ReactJS (или просто не отображающих новые данные) - PullRequest
0 голосов
/ 28 мая 2019

Проблема здесь в том, что, если мои новые данные извлекаются из моего бэкэнда (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.log(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);

Данные только показывают: нет строки, чтобы показать. Сначала я думаю, что это правильный результат, но он должен обновиться и показать мои восстановленные данные. Журналы отображают именно нужные данные и структуру массива.

Спасибо за ваше время, и я очень надеюсь получить несколько подсказок:)

EDIT: Эй, эй, я просто переписал функцию 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.log(e);
            }
            this.setState({
                rowData
            });
        };

Ответы [ 2 ]

0 голосов
/ 16 июля 2019

Здравствуйте, я просто хотел дать свой ответ, если anybo0dy смотрит на этот вопрос:

    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
    });
};

Теперь это прекрасно работает :) Я также перенес этот метод на один компонент выше, поэтому таблица данных просто получает свои данные через реквизиты, а не через состояние. Спасибо и закрыто!

0 голосов
/ 29 мая 2019

Вы уже пробовали использовать setState с функцией обратного вызова и некоторой библиотекой неизменяемости, такой как immutability-helper? Это приведет к такому коду:

import update from 'immutability-helper';
...

this.setState(prevState => update(prevState, {rowData: {$set: collectionData}});
...
...