React (16.4.1) setState () обновляет состояние на одно событие onChange за текущим событием onChange с помощью компонентаact-select - PullRequest
0 голосов
/ 12 октября 2018

У меня есть 2 компонентаact-select, и я хочу установить следующее: когда пользователь делает выбор из обоих выбранных компонентов (порядок не имеет значения), запускается ajax для получения данных с сервера.Выбор из обоих этих компонентов необходим для полного заполнения параметров GET для вызова ajax.

У меня есть два обработчика для события onChange в элементах реагировать на выбор:

filterSiteSelect(selection) {
    const siteId = selection.id;
    const siteName = selection.name;

    this.setState({
        siteId, siteName
    }, this.getTableData());
}

filterLineTypeSelect(selection) {
    const lineTypeId = selection.id;
    const lineTypeName = selection.name;

    this.setState({
        lineTypeId, lineTypeName
    }, this.getTableData());
}

И мой метод getTableData () выглядит следующим образом:

getTableData() {
    const {
        productId, siteId, lineTypeId, stages, tableUrl
    } = this.state;

// tableUrl = `p=field&t=view&gapi=1&product_id=${productId}&site_id=${siteId}&line_type_id=${lineTypeId}&stage_ids=${stages}`

    if (productId && siteId && lineTypeId && !_.isEmpty(stages)) {
        Axios.get(tableUrl)
            .then((result) => {
                this.setState({
                    rawData: { ...result.data.data }
                });
            });
    }
}

Я испытываю такое поведение, когда пользователь выбирает опцию из второго поля выбора, вызов ajax не запускается.Пользователь должен вернуться назад и выбрать что-то еще, чтобы запустить вызов ajax, а затем он использует первый выбранный выбор.

Я также попытался использовать ComponentDidUpdate() для вызова ajax с этим кодом (яудалил данные getTable() из каждого из вызовов setState(), когда я изменил на componentDidUpdate(prevState)):

componentDidUpdate(prevState) {
    const {
        siteId, lineTypeId, stages
    } = this.state;

    if (lineTypeId !== prevState.lineTypeId && siteId !== prevState.siteId && !_.isEqual(stages, prevState.stages)) {
        this.getTableData();
    }
}

Но что происходит при использовании метода жизненного цикла componentDidUpdate(), он запускает ajax снова и снованикогда не останавливаясь, и я полагаю, что это потому, что setState() никогда не обновляет состояние для последнего выбранного компонента, с которым взаимодействовал пользователь.

Так что я думаю, что я что-то не так делаю в своем использовании / понимании *Метод 1022 * (или проблема заключается в компоненте реагирования-выбора ...).

Любая идея, помощь или обсуждение того, чего я пытаюсь достичь, будет принята с благодарностью!

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

Когда вы передаете второй аргумент setState(), например, setState({foo: bar}, <something>), <something> должна быть функцией обратного вызова , которая вызывается, когда setState() закончит обновление.В вашем коде вместо передачи функции this.getTableData в качестве аргумента вы передаете выражение , возвращаемое при вызове this.getTableData(), в данном случае undefined.

В вашем кодездесь:

filterSiteSelect(selection) {
    const siteId = selection.id;
    const siteName = selection.name;

    this.setState({
        siteId, siteName
    }, this.getTableData());
}

filterLineTypeSelect(selection) {
    const lineTypeId = selection.id;
    const lineTypeName = selection.name;

    this.setState({
        lineTypeId, lineTypeName
    }, this.getTableData());
}

Когда вы синхронно вызываете setState() и добавляете обновление состояния в очередь, вы также синхронно вызываете this.getTableData(), который запускается немедленно, проверяет некоторые логические значения в переменных состояния, возможно пытаетсясделать ajax-вызов и т. д.

Попробуйте просто удалить (), чтобы передать функцию непосредственно в setState в качестве аргумента вместо случайного вызова функции.:)

filterSiteSelect(selection) {
    const siteId = selection.id;
    const siteName = selection.name;

    this.setState({
        siteId, siteName
    }, this.getTableData);
}

filterLineTypeSelect(selection) {
    const lineTypeId = selection.id;
    const lineTypeName = selection.name;

    this.setState({
        lineTypeId, lineTypeName
    }, this.getTableData);
}
0 голосов
/ 12 октября 2018
Второй параметр

setState является обратным вызовом.Это означает, что вы должны передавать ссылку на вызываемую функцию вместо вызова самой функции.

this.setState({
    siteId, siteName
}, this.getTableData());

Должно быть

this.setState({
    siteId, siteName
}, this.getTableData);
...