反应父组件的this.state在子组件的构造函数之后调用

问题描述 投票:0回答:1

我在反应中遇到了一些违反直觉的行为(至少对我而言)。我有一个API调用,返回一些要显示的JSON。我希望此调用的结果处于父组件(“问题容器”)的状态,并作为道具传递给其子组件(“问题”)。

我在子组件中得到了未定义的结果,所以我在4个不同的位置进行了一些控制台日志记录,以查看发生了什么:在每个构造函数中一次,在每个组件中一次使用“ get.ProblemsFromAPI()在“ this.state”中“功能。

父组件:

class ProblemContainer extends React.Component {
  constructor(props) {
    super(props);
    this.state =  {
      problem_set: getProblemsFromAPI()
    };
    {console.log(this.state.problem_set, 'parent constructor')}
  }


  render() {
    return(
      <div>
        <Problem problem_set={this.problem_set} />
      </div>
    )
  }

}

function getProblemsFromAPI(problem_set = {}) {
  fetch("http://localhost:5000/api/problem_set/5")
    .then(response => response.json())
    .then((data) => {console.log(data, 'set state of parent'); return data});
  }

子组件:

class Problem extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      current_problem: '',
      problem_set: getProblemsFromAPI()
    }
    console.log(this.props, 'child constructor')
  }


    render() {
        return (
          <div>

          </div>
        );
      }

    }

function getProblemsFromAPI(problem_set = {}) {
  fetch("http://localhost:5000/api/problem_set/5")
    .then(response => response.json())
    .then((data) => {console.log(data, 'set state of child'); return data});
  }

我在控制台中看到的是:

  1. “父级构造函数”
  2. “子构造函数”
  3. “设置父级状态”
  4. “设置孩子的状态”

这很奇怪,因为父组件的“ this.state”构造函数应该是顺序调用的第一件事。我可以将API调用放到子组件的componentDidMount中,这不是问题。我只是不了解这种行为。

之所以会发生,是因为它是一个函数调用而不是一个值?我对javascript和反应都是陌生的。任何建议都会有所帮助!

谢谢

javascript reactjs react-props react-state
1个回答
0
投票

[从外部API获取数据或任何状态变量更新的任何副作用,如果使用类组件,则应在componentDidMount生命周期方法中安装组件,如果使用功能性组件,则应在useEffect挂钩中安装。如您所言,您希望ProblemContainer将数据传递给它的孩子。 ProblemContainer应该负责获取数据。

例如,

class ProblemContainer extends React.Component {
  constructor(props) {
    super(props);
    this.state =  {
      problem_set: null,
      error: undefined
    };
  }

  componentDidMount() {
   fetch("http://localhost:5000/api/problem_set/5")
     .then(response => response.json())
     .then((data) => {this.setState({problem_set: data})});
     // never leave a promise with out catching the error
     .catch(error => {
       // you can console.log the error to see what is going wrong

       this.setState({problem_set: null, error: error})
     })
  } 




  render() {

    return(
      <div>
        <Problem problem_set={this.state.problem_set} /> // you need to pass the prop like this
      </div>
    )
  }

}


在您的问题组件中,

class Problem extends React.Component {
  // you have access to the problem_set via this.props.problem_set
    render() {
       console.log(this.props.problem_set) // should show the expected result
        return (
          <div>
             // component logic
          </div>
        );
      }

    }

© www.soinside.com 2019 - 2024. All rights reserved.