在React中从父组件到子组件共享状态

Sha*_*awn 5 javascript reactjs material-ui react-redux

我在将父组件的状态绑定到孩子的状态时遇到问题。看一下代码:

父组件:

    class ParentForm extends React.Component {
        constructor(){
            super();
            this.state = {
                showDialog: false
            };
        }

        toggleDialog() {
            this.setState({showDialog: !this.state.showDialog});
        }

        return (
                <div >
                    <Button color='primary' onClick={() => this.toggleDialog()}></Button>
                    <MyDialog open={this.state.showDialog}/>
                </div>
        );
    }
Run Code Online (Sandbox Code Playgroud)

子组件:

export default class MyDialog extends Component {
    constructor(props){
        super(props);
        this.state = {
            open: this.props.open
        };
    }

  handleRequestClose = () => {
    this.setState({ open: false });
  };

  render() {
    return (
      <div>
        <Dialog
          fullScreen
          open={this.state.open}
          onRequestClose={() => this.handleRequestClose()}
          transition={<Slide direction="up" />}
        >
         <DialogTitle>{'Title'}</DialogTitle>
          <DialogContent>
            <DialogContentText>
              This is my dialog
            </DialogContentText>
          </DialogContent>
          <DialogActions>
            <Button onClick={() => this.handleRequestClose()} color="primary">Close</Button>
          </DialogActions>
        </Dialog>
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

在父组件中,如果我将state.showDialog属性设为true,则在页面加载时将打开对话框。但是,一旦我关闭它一次,就再也无法打开它。如果将其设置为false,则在页面加载时不会加载,即使单击父组件上的按钮,也永远无法打开对话框。预先感谢您抽出宝贵的时间为您提供帮助。

Shu*_*tri 6

由于您是根据父级设置本地状态,因此您需要使用v16.3.0componentWillReceiveProps之前或之后的版本,因为您的状态仅在第一次设置时设置,以后再也没有设置。但是,您甚至不需要组件中的局部状态,您就可以利用子组件与父组件进行通信。getDerivedStateFromProps/memoization/key modificationMyDialogProps

父级

class ParentForm extends React.Component {
        constructor(){
            super();
            this.state = {
                showDialog: false
            };
        }

        toggleDialog() {
            this.setState({showDialog: !this.state.showDialog});
        }
        closeDialog() {
           this.setState({showDialog: false})
        }
        return (
                <div >
                    <Button color='primary' onClick={ this.toggleDialog}></Button>
                    <MyDialog open={this.state.showDialog} closeDialog={this.closeDialog}/>
                </div>
        );
    }
Run Code Online (Sandbox Code Playgroud)

MyDialog(子级)

export default class MyDialog extends Component {
  constructor(props){
    super(props);    
  }

  render() {
    return (
      <div>
        <Dialog fullScreen open={this.props.open} onRequestClose={this.props.closeDialog} transition={<Slide direction="up" />}>
         <DialogTitle>{'Title'}</DialogTitle>
          <DialogContent>
            <DialogContentText>
              This is my dialog
            </DialogContentText>
          </DialogContent>
          <DialogActions>
            <Button onClick={this.props.closeDialog} color="primary">Close</Button>
          </DialogActions>
        </Dialog>
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)