下拉选择组件状态落后一步

时间:2019-08-04 00:52:15

标签: reactjs

我不知道为什么所选的下拉值在URL搜索参数字符串中落后一步。我的网址是这样的:http://localhost/?dropdownsel=。下面是我的代码:

//App.js

//update params value
function setParams({ dropdownsel }) {
  const searchParams = new URLSearchParams();

  searchParams.set("dropdownsel", dropdownsel);

  return searchParams.toString();
}

class App extends Component {
  state = {
    dropdownsel: ""
  };
  //update url params
  updateURL = () => {
    const url = setParams({
      dropdownsel: this.state.dropdownsel
    });
    //do not forget the "?" !
    this.props.history.push(`?${url}`);
  };
  onDropdownChange = dropdownsel => {
    this.setState({ dropdwonsel: dropdownsel });
    this.updateURL();
  };
  render() {
    return (
      <Dropdownsel
        onChange={this.onDropdownselChange}
        value={this.state.dropdownsel}
      />
    );
  }
}

下面是下拉菜单组件代码:

//Dropdownsel.js

const attrData = [{ id: 1, value: AA }, { id: 2, value: BB }];
class Dropdownsel extends Component {
  onDropdownChange = event => {
    this.props.onChange(event.target.value);
  };
  render() {
    return (
      <div>
        <select value={this.props.value} onChange={this.onDropdownChange}>
          <option value="">Select</option>
          {attrData.map(item => (
            <option key={item.id} value={item.value}>
              {" "}
              {item.name}
            </option>
          ))}
        </select>
      </div>
    );
  }
}
export default Dropdownsel;

2 个答案:

答案 0 :(得分:1)

感谢格式化我的代码。我不知道每次发帖时都该怎么做。我自己弄清楚了。我需要对updateURL()进行回调,因为不会立即执行setState()。所以我的代码应该像下面这样修改:

onDropdownChange = (dropdownsel) => {

this.setState({ dropdwonsel:dropdownsel }, ()=>{this.updateURL();
});

};

答案 1 :(得分:0)

发生问题是因为this.setState是异步的(就像PromisesetTimeout一样)

因此,针对您的具体情况有两种解决方法。

解决方法#1-使用回调

使用this.setState中的callback option

当您查看setState的声明时,它接受一个“可选的”回调方法,该方法在状态更新后被调用。

setState(updater[, callback])

这意味着在回调中,您可以访问已更新状态,该状态由React在后台异步调用。

因此,如果您在回调中调用this.updateURL(),则this.state.dropdownsel值将是您期望的值。

而不是

this.setState({ dropdwonsel: dropdownsel });
this.updateURL();

在回调中呼叫this.updateURL

// Note: '{ dropdwonsel }' is equal to '{ dropdwonsel: dropdwonsel }'
// If your value is same as the state, you can simplify this way
this.setState({ dropdwonsel }, () => {
  this.updateURL()
});

解决方法#2-直接传递新值

您还可以将新值作为this.updateURL()的参数直接传递(这可能会使测试更容易,因为它使您的方法依赖于可以伪造的值)。

this.setState({ dropdwonsel });
this.updateURL(dropdownsel );

现在您的this.updateURL不依赖于this.state.dropdownsel,因此您可以使用arg推送历史记录。

  //update url params
  updateURL = dropdownsel => {
    const url = setParams({
      dropdownsel
    });
    //do not forget the "?" !
    this.props.history.push(`?${url}`);
  };