改变状态

时间:2017-12-28 19:30:13

标签: reactjs

我已经创建了组件,它传递函数以将其状态更改为子级。

//parent component
setSubject = (id) => {
    this.setState({
        currentSubject: id
    });
}

<Subjects authToken = {this.state.authToken} subjects = {this.state.subjects} setSubject = {this.setSubject} />

//child component
<li onClick={() => this.props.setSubject(subject.id)}>Egzamino programa</li>

该状态被传递给另一个组件。

 <Sections authToken = {this.state.authToken} subject = {this.state.currentSubject} />

从那里我使用componentDidUpdate()方法来处理这个变化:

componentDidUpdate() {
    if (this.props.subject) {            
        axios.get(`http://localhost:3000/api/subjects/${this.props.subject}/sections?access_token=${this.props.authToken}`)
            .then(response => {
                this.setState({
                    sections: response.data
                })
            }).catch(err => {
                console.log(err)
            })
    }
}

一切都按预期工作,但是当我在通过Subjects组件设置currentSubject后,在Sections组件中尝试console.log时,console.log执行无数次(我猜是获取请求。 ..)这不是goot,是吗?我无法理解为什么会发生这种情况。

1 个答案:

答案 0 :(得分:0)

该错误发生在componentDidUpdate方法中。

您正在使用

更新状态
   this.setState({ 
     sections: response.data
   })

当你这样做时,将调用componentDidUpdate生命周期方法,并且你有无限循环。

您可以使用锁定来快速解决此问题。但是可能有更好的设计来解决您的问题。

快速修复示例:

if (this.props.subject && !this.state.sectionsRequested) {
  this.setState({
    sectionsRequested: true,
  });
  axios.get(`http://localhost:3000/api/subjects/${this.props.subject}/sections?access_token=${this.props.authToken}`)
    .then(response => {
      this.setState({
        sections: response.data,
      });
    })
    .catch(err => {
      console.log(err);
    });
}

最好在您的情况下使用componentWillReceiveProps。 您有兴趣根据this.props.subject值获取数据。我可以看到,因为您将其用作网址查询的一部分。

您可能有兴趣使用componentWillReceivePropscomponentDidMount代替componentDidUpdate

componentDidMount(){
  if(this.props.subject){
    /* code from componentDidUpdate */
  }
}

componentWillReceiveProps(nextProps){
  if(nextProps.subject && this.props.subject !== nextProps.subject){
    /* code from componentDidUpdate */
  }
}