代码之家  ›  专栏  ›  技术社区  ›  Sahand

这状态即使在此之后,也未设置查询。setState({查询:值})调用[重复]

  •  0
  • Sahand  · 技术社区  · 8 年前

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

    例如,如果文本框为空,则用户在 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”。就好像 这状态查询 始终落后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 回复  |  直到 8 年前
        1
  •  1
  •   T.J. Crowder    5 年前

    这是因为 state updates are asynchronous :

    React可批量多个 setState() 调用单个性能更新。

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

    上面写着 “” 这道具 这状态 也许 异步更新“ 但它几乎应该说 当然,更新当前始终是异步的,它可能是批处理的,也可能不是批处理的。

    如果你只需要在 这状态 已更新,请使用 second argument ,这是进行更新时的回调。

        2
  •  1
  •   Roy Wang    8 年前

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

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