首页 > 解决方案 > this.state.query 即使在 this.setState({query:value}) 调用之后也没有设置

问题描述

我有一个组件,其中包含用户在文本框中插入内容时的处理函数。完成后,query状态对象中的字段应设置为文本框的值。

例如,如果文本框是空的,然后用户输入“s”,在handleInput(),我会做this.setState({event.target.value}),应该设置this.state.query为“s”。但这不起作用。

当我输入“s”时,该行alert("setting query to "+this.state.query);显示我"setting query to",而不是预期的"setting query to s"。这对我来说真的很奇怪,因为该行alert(event.target.value)打印出“s”,所以值肯定是 in event.target.value

然后,如果我输入另一个字符,比如“a”,警报会显示“将查询设置为 s”。就好像this.state.query一直落后1个字一样。这是代码:

class Search extends Component {
  constructor(props){
    super(props);
    let today = new Date();
    this.state = {
      searchSuggestion: 'Search for tweets here',
      anchorEl: null,
      date: today.toJSON(),
      geocode: undefined,
      page: 0,
      placeName: 'the World',
      query: ''
    }
    // Defining debounce is needed in constructor 
    this.searchTweets = debounce(500, this.searchTweets);
    this.searchGeocode = debounce(500, this.searchGeocode);
  }

  componentDidMount() {
    modelInstance.addObserver(this);
  }

  handleInput = event => {
    alert("Handling input");
    let query = event.target.value;
    alert(event.target.value); // "s"
    this.setState({
      query: event.target.value
    });
    alert("setting query to "+this.state.query); // outputs "setting query to". this.state.query isn't set to anything!
    let until = new Date(this.state.date);
    this.searchTweets(query, this.state.geocode, until);
  }

  // Searches tweets until date
  searchTweets = (query, location, date) => {
    this.props.handleStatusChange('INITIAL');
    modelInstance.searchTweets(query, location, date).then(result => {
      modelInstance.setTweets(result);
      this.props.handleStatusChange('LOADED');
      this.setState({
        data: result
      });
    }).catch(() => {
      this.props.handleStatusChange('ERROR');
    });
  }

  render(){
    return(
        <div className='search'>
          <Row id='searchInput'>
            <SearchInput handleInput={this.handleInput.bind(this)} searchInput={this.state.searchInput} searchSuggestion={this.state.searchSuggestion} page={1}/>
          </Row>
          <Row>
            <SearchNav page={this.state.page}/>
          </Row>
          <Row id='date-location'>
            <Col xs={2} sm={2} md={2} className='text'>
              <p>UNTIL</p>
            </Col>
            <Col xs={4} sm={4} md={4} className='date'>
              <SearchDate date={this.state.date} anchorEl={this.state.anchorEl} click={this.handleClick} dayChange={this.onDayChange}/>
            </Col>
            <Col xs={2} sm={2} md={2} className='text'>
              <p>IN</p>
            </Col>
            <Col xs={4} sm={4} md={4} className='location'>
              <SearchLocation placeName = {this.state.placeName} handleLocation={this.handleLocation.bind(this)}/>
            </Col>

          </Row>
        </div>
    )
  }
}

export default Search;

怎么会这样?

标签: javascriptreactjs

解决方案


这是因为状态更新是异步的

React 可以将多个setState()调用批处理到单个更新中以提高性能。

因为this.propsthis.state可能会异步更新,所以您不应该依赖它们的值来计算下一个状态。

它说this.props并且this.state 可能异步更新”,但几乎应该说,更新当前始终是异步的,它可能会或可能不会被批处理。

如果您需要在更新后才做某事this.state,请使用第二个参数,它是更新完成时的回调。


推荐阅读