Модальный компонент React открыт при загрузке и никогда не закрывается

#javascript #reactjs

Вопрос:

Я экспериментирую с модалом, который открывается, когда я нажимаю на кнопку, но он открыт в начале и никогда не закрывается.

Как убедиться, что он закрыт при монтировании и закрывается, когда я нажимаю за пределами окна сообщения ?

Я адаптирую модальную демонстрацию из материального ядра:

 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 >
        );
    }
}
 

Ответ №1:

Вы использовали и обновляли два разных значения состояния open и setOpen . Вот почему она открывалась и никогда не закрывалась. Обновил свой код в песочнице. Другая проблема заключалась в том, что вы использовали open={() => this.state.open()} для модального состояния, которое всегда возвращало значение true. Вместо этого вам нужно использовать open={this.state.open}

вот полный код.

 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; 

Ответ №2:

Вы ошиблись между работой с классами и крючками. Поскольку вы используете классы и setState , вы должны установить состояние переменной open , которая определяет, открыт ли модал или нет (это логическое значение).

Свойство open модального компонента пользовательского интерфейса Material ожидает логическое значение, которое определяет, должен ли модал находиться в открытом состоянии или нет. Вы передаете свою государственную собственность open в open собственность, и это нормально. Но вам нужно обновлять его, setState когда это необходимо.

Итак, вместо this.setState({ setOpen: true }); и this.setState({ setOpen: false }); Вы должны использовать this.setState({ open: true }); и this.setState({ open: false }); .

Государственная собственность setOpen в этом случае не нужна. Это фиксированный код:

 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 >
        );
    }
} 

Комментарии:

1. Также <Modal open={() => this.state.open()} должно быть <Modal open={this.state.open} , не так ли ?

2. ДА. Вы правы, я отредактирую его