Home > other >  React component modal is open at load and never closes
React component modal is open at load and never closes

Time:09-23

I'm experimenting a modal that opens when I click on a button, but it's open at the beginning and it never closes.

How to make sure it is closed at mount and that is closes when I click outside the message box ?

I'm adapting the modal demo from material core:

import React, { Component } from 'react';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Typography from '@mui/material/Typography';
import Modal from '@mui/material/Modal';

const style = {
    position: 'absolute',
    top: '50%',
    left: '50%',
    transform: 'translate(-50%, -50%)',
    width: 400,
    bgcolor: 'background.paper',
    border: '2px solid #000',
    boxShadow: 24,
    p: 4
};

export class Contact extends Component {
    constructor(props) {
        super(props);
        this.state = {
            open: false,
            setOpen: false
        }
        this.handleOpen = this.handleOpen.bind(this);
        this.handleClose = this.handleClose.bind(this);
    }
    static displayName = Contact.name;
    handleOpen() { this.setState({ setOpen: true }); }
    handleClose() { this.setState({ setOpen: false }); }
 
    render() {

        return(
            <div>
                <div className="center">
                    <Button onClick={() => this.handleOpen()}>Contact us</Button>
                </div>
                <Modal open={() => this.state.open()} onClose={()=> this.handleClose()}
                aria-labelledby="modal-modal-title" aria-describedby="modal-modal-description">
                    <Box sx={style}>
                      <Typography id="modal-modal-title" variant="h6" component="h2">
                          Contact us
                      </Typography>
                      <Typography id="modal-modal-description" sx={{ mt: 2 }}>
                          Contact us at hello @ mycompany.com
                      </Typography>
                    </Box>
                </Modal>
            </div >
        );
    }
}

CodePudding user response:

You were using and updating two different state values open and setOpen. That's why it was opening and never closes. Updated your code in the sandbox. Another issue was you were using open={() => this.state.open()} for modal state, which was always returning true. Instead you need to use the open={this.state.open}

here is the complete code.

import React, { Component } from "react";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import Modal from "@mui/material/Modal";

const style = {
  position: "absolute",
  top: "50%",
  left: "50%",
  transform: "translate(-50%, -50%)",
  width: 400,
  bgcolor: "background.paper",
  border: "2px solid #000",
  boxShadow: 24,
  p: 4
};

class Contact extends Component {
  constructor(props) {
    super(props);
    this.state = {
      open: false
    };
    this.handleOpen = this.handleOpen.bind(this);
    this.handleClose = this.handleClose.bind(this);
  }
  static displayName = Contact.name;
  handleOpen() {
    this.setState({ open: true });
  }
  handleClose() {
    this.setState({ open: false });
  }

  render() {
    return (
      <div>
        <div className="center">
          <Button onClick={this.handleOpen}>Contact us</Button>
        </div>
        <Modal
          open={this.state.open}
          onClose={this.handleClose}
          aria-labelledby="modal-modal-title"
          aria-describedby="modal-modal-description"
        >
          <Box sx={style}>
            <Typography id="modal-modal-title" variant="h6" component="h2">
              Contact us
            </Typography>
            <Typography id="modal-modal-description" sx={{ mt: 2 }}>
              Contact us at hello @ mycompany.com
            </Typography>
          </Box>
        </Modal>
      </div>
    );
  }
}

export default Contact;

CodePudding user response:

You got mistaken between working with classes and hooks. Since you are using classes and setState, you should set the state of the variable open that determines if the modal is open or not (it is a boolean value).

The property open of Material UI's Modal component expect a boolean value that determines if the modal should be in open state or not. You are assigning the state property open of yours into the open property, which is okay. But you need to update it with setState when needed.

So, instead of this.setState({ setOpen: true }); and this.setState({ setOpen: false }); You should use this.setState({ open: true }); and this.setState({ open: false });.

The state property setOpen is unnecesary in this case. This is the fixed code:

import React, { Component } from 'react';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Typography from '@mui/material/Typography';
import Modal from '@mui/material/Modal';

const style = {
    position: 'absolute',
    top: '50%',
    left: '50%',
    transform: 'translate(-50%, -50%)',
    width: 400,
    bgcolor: 'background.paper',
    border: '2px solid #000',
    boxShadow: 24,
    p: 4
};

export class Contact extends Component {
    constructor(props) {
        super(props);
        this.state = {
            open: false
        }
        this.handleOpen = this.handleOpen.bind(this);
        this.handleClose = this.handleClose.bind(this);
    }
    static displayName = Contact.name;
    handleOpen() { this.setState({ open: true }); }
    handleClose() { this.setState({ open: false }); }
 
    render() {

        return(
            <div>
                <div className="center">
                    <Button onClick={() => this.handleOpen()}>Contact us</Button>
                </div>
                <Modal open={this.state.open} onClose={()=> this.handleClose()}
                aria-labelledby="modal-modal-title" aria-describedby="modal-modal-description">
                    <Box sx={style}>
                      <Typography id="modal-modal-title" variant="h6" component="h2">
                          Contact us
                      </Typography>
                      <Typography id="modal-modal-description" sx={{ mt: 2 }}>
                          Contact us at hello @ mycompany.com
                      </Typography>
                    </Box>
                </Modal>
            </div >
        );
    }
}

  • Related