简体   繁体   English

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

I have 2 react-select components and the behavior I wish to set is that when the user makes their selection from both select components (order does not matter) then an ajax will be triggered to pull the data from the server. 我有2个反应选择组件,我要设置的行为是,当用户从两个选择组件中进行选择时(顺序无关紧要),那么将触发ajax从服务器中提取数据。 The selection from both of these components is required to fully populate the GET parameters for the ajax call. 需要从这两个组件中进行选择才能完全填充ajax调用的GET参数。

I have these 2 handlers for the onChange event on the react-select elements: 我在react-select元素上具有onChange事件的以下2个处理程序:

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

And my getTableData() method looks like: 我的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 }
                });
            });
    }
}

The behavior I am experiencing is that when the user select's an option from the second select box the ajax call does not fire. 我遇到的行为是,当用户从第二个选择框中选择一个选项时,ajax调用不会触发。 The user needs to go back and select something else to get the ajax call to fire and then it uses the first selection they chose. 用户需要返回并选择其他内容来触发ajax调用,然后使用他们选择的第一个选择。

I also tried to use ComponentDidUpdate() for the ajax call with this code (I removed the getTable() data from each of the setState() calls when I changed to componentDidUpdate(prevState) ): 我还尝试通过此代码对ajax调用使用ComponentDidUpdate() setState()当我更改为componentDidUpdate(prevState)时,我从每个setState()调用中删除了getTable()数据):

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

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

But what happens when using the componentDidUpdate() lifecycle method it fires the ajax over and over never stoping and I believe that is because the setState() is never updating the state for the last select component the user interacted with. 但是,当使用componentDidUpdate()生命周期方法时,会反复触发ajax,并且永不停止,这是因为setState()永远不会更新用户与之交互的最后一个选择组件的状态。

So I think I'm doing something wrong in my use/understanding of the setState() method (or the issue lies in the react-select component...). 所以我认为我在使用/理解setState()方法时做错了(或者问题出在react-select组件中...)。

Any insight, assistance, or discussion of what I'm trying to accomplish would be greatly appreciated! 对于我要完成的任务的任何见解,帮助或讨论将不胜感激!

When you pass a second argument to setState() , eg setState({foo: bar}, <something>) , the <something> is supposed to be a callback function that gets called when setState() has finished updating. 当您将第二个参数传递给setState() ,例如setState({foo: bar}, <something>)<something>应该是当setState()完成更新时调用的回调函数 In your code, instead of passing your function this.getTableData as an argument, you are passing the expression returned from calling this.getTableData() , in this case undefined . 在您的代码中,不是传递函数this.getTableData作为参数,而是传递从调用 this.getTableData() 返回表达式 ,在本例中为undefined

In your code here: 在您的代码中:

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

When you synchronously call setState() and add a state update to the queue, you are also synchronously calling this.getTableData() which runs immediately, checks some booleans in your state variables, maybe tries to do an ajax call, etc. 当您同步调用setState()并将状态更新添加到队列中时,您还同步调用this.getTableData() ,它立即运行,检查状态变量中的一些布尔值,也许尝试执行ajax调用等。

Try simply removing the () so that you're passing the function directly into setState as an argument instead of accidentally calling the function. 尝试简单地删除()以便将函数直接作为参数传递给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 's second parameter is a callback. setState的第二个参数是回调。 That means you should be passing a reference to the function to call, instead of calling the function itself. 这意味着您应该传递对要调用的函数的引用,而不是调用函数本身。

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

Should be 应该

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM