在React中更新父项中的状态时如何更新子项中的props?

时间:2019-04-30 05:58:13

标签: javascript reactjs

我正在开发具有多个组件和API的React应用。我有一个与API连接的Parent组件。我有一个子组件,该子组件具有显示API数据的弹出模式。我在子组件内部创建了模式,并在收到API数据时在父组件内部调用了该模式。现在,我将通过Material UI通告进度对此进行更新,以避免延迟API响应的可用性降低。

我在父组件中调用API,并将初始状态isLoading设置为true。在API成功方法中,我将isLoading设置为false。同时,我在子组件中打开模态,并将isLoading状态作为带有API数据的prop发送。在子组件中,我正在接收这些道具。最初,我将isLoading设置为True,并将状态设置为True。然后,我在父母中的API成功时等待错误,但是问题甚至在API成功之后,我也无法立即将更新的isLoading(false)从父母传给孩子。但是,它正在渲染函数中更新,因此我可以获得projectAllData。我只是无法在ComponentDidMount中使用更新的isLoading设置状态

父母:

class Taskboard extends Component {
  constructor(props) {
    super(props);
    this.state = {
      projectAllData: undefined,
      open: false,
      isLoading: true,
    };
  }

  getPojectId = (projectId) => {
    this.setState({ open: true })

    API.get('project/' + projectId)
      .then(({ data }) => {
        this.setState({
          projectAllData: data.response,
          isLoading: false,
        });
      })
      .catch((err) => {
        console.log("AXIOS ERROR: ", err);
      })
  }

  render(){
    return(
      {
          this.state.open ?
            <ProjectModal
              handleOpen={this.state.open}
              handleClosed={this.handleClose}
              projectData={this.state.projectAllData}
              isLoading={this.state.isLoading}
            /> : null
        }
    )
  }
}

孩子:

class ProjectModal extends Component {
    constructor(props) {
        super(props);
        this.state = {
            single: ''
        }
    }

    componentDidMount() {
       this.setState({ single: !this.props.isLoading? this.props.projectData.currentAssigneeName : '' }) 
       //Initially this is True and is not updating when isLoading is False
    }

    render() {
      return(
         {
           this.props.isLoading ?
             <CircularProgress/>
           :
           <Modal />
         }
      )
    }
}

3 个答案:

答案 0 :(得分:1)

componentDidMount仅被调用一次,即在初始渲染之后被调用一次。对于您的用例,您需要componentDidUpdate

componentDidUpdate(prevProps) {
  if (this.props.isLoading !== prevProps.isLoading) {    
    this.setState({ /* here goes you state update*/ })
  }
}

答案 1 :(得分:1)

只有第一次您才在componentDidMount中获得父值,之后您将获得ComponentWillReceiveProps。如果API响应延迟,则您将无法在componentDidMount中获取值,因此在子组件中,我们必须调用ComponentWillReceiveProps挂钩方法。我将在下面给出示例。

ComponentWillReceiveProps(nextProps) {
   this.setState({
       single: !nextProps.isLoading nextProps.projectData.currentAssigneeName : '' 
       }) 

}

我们也可以使用静态getDerivedStateFromProps代替ComponentWillReceiveProps

答案 2 :(得分:1)

这里简单的解决方案,您不需要状态,因为它不会改变,只需在render中设置single的值即可。

class ProjectModal extends Component {

    render() {

      const single = !this.props.isLoading 
        ? this.props.projectData.currentAssigneeName 
        : '';

      return(
        { this.props.isLoading 
          ? <CircularProgress/>
          : <Modal />
        }
      )
    }
}