I made a games page in react. When you win one, it displays a form dialog (with material-UI: https://material-ui.com/components/dialogs/#form-dialogs). Component's visibility depends on the open attribute, which is changed with "handleClickOpen" when you push the button. I wanted to reuse code so I made a component that contains the dialog. Here is my code so far (child class):
class Pop_dialog extends Component {
constructor(props) {
super(props)
this.state = {
open: false
}
}
handleOpen() {
console.log('A')
this.setState({ open: true })
}
handleClose() {
console.log('B')
this.setState({ open: false })
}
render() {
return (
<Dialog open={this.state.open} onClose={this.handleClose} aria-labelledby="form-dialog-title">
<DialogTitle id="form-dialog-title">Subscribe</DialogTitle>
<DialogContent>
<DialogContentText>
To subscribe to this website, please enter your email address here. We will send updates
occasionally.
</DialogContentText>
<TextField
autoFocus
margin="dense"
id="name"
label="Email Address"
type="email"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button onClick={this.handleClose} color="primary">
Cancel
</Button>
<Button onClick={this.handleClose} color="primary">
Subscribe
</Button>
</DialogActions>
</Dialog>
)
}
I call "handleOpen" within a function in the parent class:
triggerDialog() { this.dialogRef.current.handleOpen(); }
render ()
{
...
<Pop_dialog ref={this.dialogRef}/>
}
The triggerDialog function is called when I win/lost the game and it opens the form dialog fine. The problem comes when I try to close it (with the Cancel or Subscribe buttons). The page throws the next error:
I couldn´t find why it fails here but not when it use "handleOpen". By the way, this is the 4th solution that i use. I also tried using a function component with the useContext hood (It didn't work at all), passing 'open' like a prop to the child (I also could open the dialog but not close it) and turn 'open' in a session var, defined in the parent component and called in the child (I couldn't open the dialog).
I don't know if some of this ideas would work or if I need a completely new one. I am open to any kind of idea, as long as it keeps Pop_dialog reusable.
It doesn't seem as though you've bound this
to the handlers in Pop_dialog
. The result is that this
is undefined in the callback handlers.
Bind in the constructor:
class Pop_dialog extends Component {
constructor(props) {
super(props)
this.state = {
open: false
}
this.handleOpen = this.handleOpen.bind(this);
this.handleClose = this.handleClose.bind(this);
}
handleOpen() {
console.log('A')
this.setState({ open: true })
}
handleClose() {
console.log('B')
this.setState({ open: false })
}
...
Or convert the handlers to arrow functions so this
of the class is bound automatically.
class Pop_dialog extends Component {
constructor(props) {
super(props)
this.state = {
open: false
}
}
handleOpen = () => {
console.log('A')
this.setState({ open: true })
}
handleClose = () => {
console.log('B')
this.setState({ open: false })
}
...