即使在this.setState({query:value})之后调用

时间:2018-04-29 13:02:20

标签: javascript reactjs

我有一个组件,其中包含用户在文本框中插入内容时的处理函数。完成此操作后,状态对象中的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",因此值肯定在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;

为什么会这样?

2 个答案:

答案 0 :(得分:1)

使用setState的回调,其更新值为this.state

this.setState({
  query: event.target.value
}, () => alert(this.state.query));

答案 1 :(得分:1)

这是因为state updates are asynchronous

  

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

     

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

它说&#34; this.propsthis.state 可以异步更新&#34; 但它应该说会< / strong>是。更新始终是异步的,它可能是也可能不是批处理。

如果您只有在this.state更新后才需要执行某些操作,请使用second argument,这是更新完成时的回调。