简体   繁体   English

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

[英]React: Child component is passing it's state up to parent, but once parent has it, the parent is not updating its state

My issue here is that I have some values coming up from the SearchForm component. 我的问题是,我有一些来自SearchForm组件的值。 They're passing the correct value as arguments to the handleSearch function, but my call to setState does nothing. 他们正在将正确的值作为参数传递给handleSearch函数,但是我对setState的调用没有任何作用。 I've included console.logs to show what's stored in the variables. 我已经包含console.logs来显示变量中存储了什么。 See comments in the code below. 请参阅下面的代码中的注释。

Because my state is being passed from this component to the ResultList component as empty strings, the ResultList does not render correctly. 因为我的状态作为空字符串从该组件传递到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;

I'll elaborate on what I said in my comment: 我将详细说明我的评论:

Component#setState defers and batches state update requests for performance. Component#setState推迟并批处理状态更新请求以提高性能。 Because of this, you cannot relay on the Component.state to be updated with the new values immediately after the call. 因此,您不能在调用后立即在Component.state上进行中继以使用新值进行更新。

setState provides a second argument - a callback which is called after the state update operation is performed. setState提供了第二个参数-在执行状态更新操作之后调用的回调。 In your case, it would look like 就您而言,它看起来像

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

setState is not a synchronous function call, so calling setstate in the function might not update the state immediately. setState不是同步函数调用,因此在函数中调用setstate可能不会立即更新状态。 as from the documentation 从文档中

setState() enqueues changes to the component state and tells React that this component and its children need to be re-rendered with the updated state. setState()使更改进入组件状态并告诉React该组件及其子级需要使用更新后的状态重新呈现。 This is the primary method you use to update the user interface in response to event handlers and server responses. 这是用于响应事件处理程序和服务器响应而更新用户界面的主要方法。 Think of setState() as a request rather than an immediate command to update the component. 将setState()视为请求而不是立即更新组件的命令。 For better perceived performance, React may delay it, and then update several components in a single pass. 为了获得更好的感知性能,React可能会延迟它,然后在一次通过中更新几个组件。 React does not guarantee that the state changes are applied immediately React不能保证状态更改立即生效

so console.log(this.state.category); console.log(this.state.term); 所以console.log(this.state.category); console.log(this.state.term); console.log(this.state.category); console.log(this.state.term); will not log the updated state. 不会记录更新状态。 but if you put these statements in render function, you will see the correct state being set in next render. 但是,如果将这些语句放在render函数中,则会在下一次渲染中看到设置了正确的状态。

Read more on https://facebook.github.io/react/docs/react-component.html#setstate 进一步了解https://facebook.github.io/react/docs/react-component.html#setstate

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM