React:子组件将其状态传递给父级,但是一旦父级拥有它,父级就不会更新其状态

时间:2017-08-18 18:07:34

标签: reactjs components state

我的问题是我有一些来自SearchForm组件的值。他们将正确的值作为参数传递给handleSearch函数,但是我对setState的调用什么也没做。我已经包含了console.logs来显示存储在变量中的内容。请参阅以下代码中的注释。

因为我的状态作为空字符串从此组件传递到ResultList组件,所以ResultList无法正确呈现。

import React, { Component } from 'react';
import axios from 'axios';
import SearchForm from './components/search_form';
import ResultList from './components/results_list';

class App extends Component {
  constructor(props) {
    super(props);

    this.state = { category: '', term: '', results: [] };
    this.handleSearch = this.handleSearch.bind(this);
  }

  handleSearch(category, term) {

    //This is not setting the state!!!!!
    this.setState({ category, term });

    //The first two console.logs successfully log the arguments to this 
    function
    //The last two console.logs log empty strings even after the above 
    setState call.

    console.log("Received from form: " + category);
    console.log("Received from form: " + term);
    console.log("#################################");
    console.log(this.state.category);
    console.log(this.state.term);


    console.log('http://swapi.co/api/' + category + '/?search=' + term);
    axios.get('http://swapi.co/api/' + category + '/?search=' + 
term).then((response) => {
        let results = response.data.results;
        this.setState({ results });
        console.log(this.state.results);
    }).catch((error) => {
      console.log(error);
    });

  }

  render() {
    return (
      <div className="container panel panel-default">
        <SearchForm handleSearch={this.handleSearch}/>
        <ResultList results={this.state.results} category=
{this.state.category}/>
      </div>
    );
  }
}

export default App;

2 个答案:

答案 0 :(得分:2)

我将详细说明我在评论中所说的内容:

Component#setState推迟并批量处理性能的状态更新请求。因此,您无法在呼叫后立即使用新值更新Component.state

setState提供了第二个参数 - 在执行状态更新操作后调用的回调。在你的情况下,它看起来像

this.setState({ category, term }, () => {
  console.log(this.state.term, this.state.category)
  // now you can use them
}) 

答案 1 :(得分:0)

setState不是同步函数调用,因此在函数中调用setstate可能不会立即更新状态。从文档中

  

setState()将对组件状态的更改排入队列,并告诉React该组件及其子组件需要使用   更新状态。这是用于更新用户的主要方法   接口响应事件处理程序和服务器响应。考虑到   setState()作为请求而不是立即命令来更新   零件。为了获得更好的感知性能,React可能会延迟它,并且   然后在一次通过中更新几个组件。 React没有   保证立即应用状态更改

所以console.log(this.state.category); console.log(this.state.term); 不会记录更新的状态。但是如果你将这些语句放在渲染函数中,你会看到在下一个渲染中设置了正确的状态。

详细了解https://facebook.github.io/react/docs/react-component.html#setstate