-1

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:

enter image description here

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.

  • 1
    This problem has already been answered [here](https://stackoverflow.com/questions/33973648/react-this-is-undefined-inside-a-component-function) – Joyescat Aug 29 '21 at 18:24

1 Answers1

2

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 })
  }
  ...
Drew Reese
  • 165,259
  • 14
  • 153
  • 181