从父组件修改子状态

时间:2018-10-31 15:35:13

标签: javascript reactjs

父组件在应用栏中包含一个按钮,在绘图区域(我在其中拖放一些内容,仅用于此处的上下文)中包含一个按钮。 我想让子组件相对独立。

单击此父组件中可用的按钮时,我想更改子组件的状态。 当我使用不安全的“ componentWillReceiveProps”(并且替换功能“很少使用”时),它可以工作。 因此,我从未从父组件成功调用函数(在子组件中)。

React的最佳实践是什么?(我来自PHP / GO / Python背景)。

父类:

Class EditionView extends React.Component {

  constructor(props) {
    super(props)
    var drawingModel = this.emptyDrawingModel();
    this.state= {drawingModel:drawingModel};
  }

  emptyDrawingModel(){
    var drawingModel = []
    for (var i=0; i<3; i++) {
      drawingModel.push('')
    }
    return drawingModel;
  }

  resetDrawingArea() {
    console.log("tmp:", this);
    var drawingModel = this.emptyDrawingModel();
    this.setState({drawingModel: drawingModel});
  }

  render() {
    console.log(this.state);
    return (
      <div>
        <AppBar position="static" color="primary">
          <Typography variant="h6" color="inherit">
              Title
          </Typography>
          <Toolbar>
            <Button variant='contained' component='span' onClick={()=>{this.resetDrawingArea()}}>Reset</Button>
          </Toolbar>
        </AppBar>
        <Grid container>
          <Grid item sm={9}>
            <DrawingArea id='drawing' initialModel={this.state.drawingModel}/>
          </Grid>
        </Grid>
      </div>
    );
  }

}

export default EditionView;

儿童班

class DrawingArea extends React.Component {

  constructor(props) {
    super(props)
    this.state = {content:props.initialModel};
    //this.reset = this.reset.bind(this); 
    //this.reset = this.reset();
  }

  /*
  //WORKs but UNSAFE
  componentWillReceiveProps(){
    console.log("componentWillMount", this)
    this.setState({content: this.props.initialModel});
  }
  */

  reset(){
    console.log('in Drawing Area > reset')
    var model = this.props.initialModel;
    this.setState({content:model})
  }

  render() {
    console.log("render drawing area", this)
    var items = this.state.content.map((val, i) =>{
      var item;
      if (val === ''){
        // code for if 
      } else {
        // code for else
      }
      return item;
    });

    return(
      <div id="main-area">
        <Grid container>{items}</Grid>
      </div>
    )
  }
}

export default DrawingArea;

3 个答案:

答案 0 :(得分:2)

使用getDerivedStateFromProps

  在初始安装和后续更新上,都在调用render方法之前立即调用

getDerivedStateFromProps 。它应该返回一个对象以更新状态,或者返回null则不更新任何内容。

class DrawingArea extends React.Component {

    static getDerivedStateFromProps(props) {
         return {
            content: props.initialModel
         }
    }

  ...
}

答案 1 :(得分:1)

在子组件DrawingArea中,由于您在this.state函数中使用了render,因此您可能需要实现生命周期事件getderivedstatefromprops

另一种选择是在this.props函数中使用render。这应该适用于您提供的简单示例。它将继续为您工作,直到需要在DrawingArea中存储状态的时间点为止(如果有的话)。

答案 2 :(得分:0)

只要您在子代的构造函数中具有

,就不需要componentWillReceiveProps()
constructor(props) {
  super(props)
    this.state = {
      content: this.props.initialModel
    }
}

,只要您继续在子组件中使用this.state.content

当this.state.drawingModel更改时,父组件将重新渲染,使子组件接收其新的道具,并且只要映射到子组件的状态,该子组件也将重新渲染