React (16.4.1) setState() 用react-select组件更新当前onChange事件后面的状态一个onChange事件

React (16.4.1) setState() updates state one onChange event behind the current onChange event with react-select component

我有 2 个 react-select 组件,我希望设置的行为是当用户从两个 select 组件生成他们的 selection 时(顺序无关紧要)然后将触发 ajax 从服务器中提取数据。需要来自这两个组件的 selection 才能完全填充 ajax 调用的 GET 参数。

我在 react-select 元素上有这两个 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 }
                });
            });
    }
}

我遇到的行为是,当用户 select 从第二个 select 框中选择一个选项时,ajax 调用不会触发。用户需要返回并 select 其他东西来触发 ajax 调用,然后它使用他们选择的第一个 selection。

我还尝试使用此代码将 ComponentDidUpdate() 用于 ajax 调用(当我更改为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() 永远不会更新状态用户与之交互的最后 select 个组件。

所以我认为我在 setState() 方法的 use/understanding 中做错了什么(或者问题出在 react-select 组件中...)。

任何对我正在努力完成的事情的见解、帮助或讨论都将不胜感激!

setState的第二个参数是回调。这意味着您应该传递对要调用的函数的引用,而不是调用函数本身。

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

应该是

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

当您将第二个参数传递给 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);
}