我遇到了将父组件的状态绑定到子状态的问题。看一下代码:
父组件:
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>
);
}
子组件:
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>
);
}
}
在Parent Component中,如果我将state.showDialog属性设为true,则在加载页面时将打开该对话框。但是一旦我关闭它一次,我再也无法打开它了。如果我将其设置为false,则在页面加载时不会加载,即使单击父组件上的按钮,也无法打开对话框。提前感谢您抽出宝贵时间提供帮助。
答案 0 :(得分:5)
由于您是根据父级设置本地状态,因此您需要在 v16.3.0 之后使用componentWillReceiveProps
或之后使用getDerivedStateFromProps/memoization/key modification
,因为您的状态已设置只在第一次,从此之后。但是,您甚至不需要MyDialog
组件中的本地状态,您只需使用Props
并从子组件传递到父组件。
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>
);
}
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>
);
}
}
答案 1 :(得分:2)
handleRequestClose方法应该是这样的。
handleRequestClose = () => {
this.setState({ open: this.props.open});
};
编辑1。
关闭对话框时,还需要更新父状态。
toggleDialog(val) {
if(val){
this.setState({showDialog: val});
}else {
this.setState({showDialog: !this.state.showDialog});
}
}
return (
<div >
<Button color='primary' onClick={() => this.toggleDialog()}></Button>
<MyDialog toggleDialog = {this.toggleDialog} open={this.state.showDialog}/>
</div>
);
和
componentWillRecieveProps(nextProps) {//Lifecycle method to get the updated props
this.setState({ open: nextProps.open });
}
handleRequestClose = () => {
this.setState({ open: !this.state.open},()=>{
this.props.toggleDialog (this.state.open);
});
};
答案 2 :(得分:2)
您的子组件当前仅接收父级的showDialog道具值一次,只有在构造函数中启动它时才会收到。
您需要使用componentWillRecieveProps
和子组件的setState以及更新后的值。
所以:
componentWillRecieveProps(nextProps) {
this.setState({ open: nextProps.open });
}
编辑:需要使用nextProps,而不是this.props
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>
);
}
export default class MyDialog extends Component {
handleRequestClose = () => {
this.props.closeDialog();
};
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>
);
}
}