React (16.4.1) setState() обновляет состояние на одно событие onChange за текущим событием onChange с помощью компонента act-select
У меня есть 2 компонента реакции-выбора, и я хочу установить следующее: когда пользователь делает выбор из обоих выбранных компонентов (порядок не имеет значения), то запускается ajax для получения данных с сервера. Выбор из обоих этих компонентов необходим для полного заполнения параметров GET для вызова ajax.
У меня есть эти 2 обработчика для события 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()
никогда не обновляет состояние последнего выбранного компонента, с которым взаимодействовал пользователь.
Так что я думаю, что я делаю что-то не так в своем использовании / понимании setState()
метод (или проблема заключается в компоненте act-select...).
Любая идея, помощь или обсуждение того, чего я пытаюсь достичь, будет принята с благодарностью!
2 ответа
Когда вы передаете второй аргумент 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);
}
setState
Второй параметр - это обратный вызов. Это означает, что вы должны передавать ссылку на вызываемую функцию вместо вызова самой функции.
this.setState({
siteId, siteName
}, this.getTableData());
Должно быть
this.setState({
siteId, siteName
}, this.getTableData);