Estoy experimentando con un modal que se abre cuando hago clic en un botón, pero está abierto al principio y nunca se cierra.
¿Cómo asegurarme de que esté cerrado en el montaje y que se cierre cuando hago clic fuera del cuadro de mensaje?
Estoy adaptando la demostración modal de 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 > ); } }Te equivocaste entre trabajar con clases y ganchos. Dado que está utilizando clases y setState , debe establecer el estado de la variable open que determina si el modal está abierto o no (es un valor booleano).
La propiedad open del componente modal de Material UI espera un valor booleano que determina si el modal debe estar en estado abierto o no. Estás asignando la propiedad estatal open tuya a la propiedad open , lo cual está bien. Pero debe actualizarlo con setState cuando sea necesario.
Entonces, en lugar de this.setState({ setOpen: true }); y this.setState({ setOpen: false }); Deberías usar this.setState({ open: true }); y this.setState({ open: false }); .
La propiedad estatal setOpen es necesaria en este caso. Este es el código fijo:
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 > ); } }Estaba usando y actualizando dos valores de estado diferentes open y setOpen . Por eso se abría y nunca se cierra. Actualizaste tu código en el sandbox . Otro problema fue que estaba usando open={() => this.state.open()} para el estado modal, que siempre devolvía verdadero. En su lugar, debe usar open={this.state.open}
aquí está el código completo.
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;