首页 > 解决方案 > 如何使用material-ui处理“内部链接”单击对话框(模态)

问题描述

如果用户点击了模态框内的链接,我如何关闭模态框?例如,他们打开了一个登录表单的模式——但也有一个忘记密码的链接。如果他们点击用户被带到页面的链接 - 但模式保持打开状态?

链接将是 modalcontents 道具的一部分 - 但是关闭句柄在 modalbox 内?

<ModalBox 
  button={{"label": "Log In", "color":"primary"}}
  modalContents={
    <div className="login-form">
      <Grid container spacing={1}>
        <Grid item xs={12} sm={12}>
          <GenericForm 
            initialValues={initialLoginFormValues} 
            fields={fieldsLoginForm}
            buttons={buttonsLoginForm}
            submitHandler={this.loginFormHandler}
          />

          {errorMsg.length > 0 && 
            (
              <div className="error-text">
                {errorMsg}
              </div>
            )
          }

        </Grid>
        <Grid item xs={12} sm={12}>
          <div className="forgot-password-pane">
            <NavLink
              to="/forgotpassword"
              activeClassName="selected">Forgot password?
            </NavLink>
          </div>
        </Grid>
        <Grid item xs={12} sm={12}>
          Don't have an account? Don't worry, you can <NavLink to="/" activeClassName="selected">join here</NavLink>
        </Grid>
      </Grid>
    </div>
  }
/>

模态框

import React, { Component } from 'react';
import Modal from '@material-ui/core/Modal';
import Backdrop from '@material-ui/core/Backdrop';
import Fade from '@material-ui/core/Fade';
import Button from '@material-ui/core/Button';


import IconButton from '@material-ui/core/IconButton';
import CloseIcon from '@material-ui/icons/Close';

//import './ModalBox.scss';

class ModalBox extends Component {
    constructor(props, context) {
        super(props, context);
        this.state = { open: false };
    }

    componentDidUpdate(prevProps) {
      // Typical usage (don't forget to compare props):
      if(this.props.open !== prevProps.open) {
        if(this.props.open){
          this.handleOpen();
        }
      }
    }    

    handleOpen = () => {
      this.setState({open: !this.state.open});
    };

    handleClose = () => {
      this.setState({open: false});

      //if there is a handle close callback - invoke it
      if(this.props.handleClose) {
        this.props.handleClose();
      }
    };

    render() {
        return (
          <>
            {this.props.button &&
              (
                <Button 
                  variant="contained" 
                  color={this.props.button.color} 
                  onClick={this.handleOpen}
                >
                  {this.props.button.label}
                </Button>
              )
            }
            <Modal
              aria-labelledby="transition-modal-title"
              aria-describedby="transition-modal-description"
              className={'modalbox'}
              open={this.state.open}
              onClose={this.handleClose}
              closeAfterTransition
              BackdropComponent={Backdrop}
              BackdropProps={{
                timeout: 500,
              }}
            >
              <Fade in={this.state.open}>
                <div className={'modalboxform ' + this.props.classes}>
                  <IconButton className="close-button" onClick={this.handleClose}>
                    <CloseIcon/>
                  </IconButton>
                  {this.props.modalContents}
                </div>
              </Fade>
            </Modal>
          </>
        );
    }
}

export default ModalBox;

标签: javascriptreactjs

解决方案


我不确定这是否是生产中的最佳方式,但现在您可以通过向元素添加onClick事件侦听器来处理此问题NavLink,您的代码:

  <NavLink
     to="/forgotpassword"
     activeClassName="selected">Forgot password?
  </NavLink>

将其更改为以下内容:

  <NavLink
     to="/forgotpassword"
     activeClassName="selected"
     onClick={this.handleClose}
   >
       Forgot password?
  </NavLink>

就像将代码移动到您定义模态框组件应如何与所有导入和函数一样的位置

或者只需遵循以下代码:

import React, { Component } from 'react';
import Modal from '@material-ui/core/Modal';
import Backdrop from '@material-ui/core/Backdrop';
import Fade from '@material-ui/core/Fade';
import Button from '@material-ui/core/Button';


import IconButton from '@material-ui/core/IconButton';
import CloseIcon from '@material-ui/icons/Close';

//import './ModalBox.scss';

class ModalBox extends Component {
    constructor(props, context) {
        super(props, context);
        this.state = { open: false };
    }

    componentDidUpdate(prevProps) {
      // Typical usage (don't forget to compare props):
      if(this.props.open !== prevProps.open) {
        if(this.props.open){
          this.handleOpen();
        }
      }
    }    

    handleOpen = () => {
      this.setState({open: !this.state.open});
    };

    handleClose = () => {
      this.setState({open: false});

      //if there is a handle close callback - invoke it
      if(this.props.handleClose) {
        this.props.handleClose();
      }
    };

    render() {
        return (
          <>
            {this.props.button &&
              (
                <Button 
                  variant="contained" 
                  color={this.props.button.color} 
                  onClick={this.handleOpen}
                >
                  {this.props.button.label}
                </Button>
              )
            }
            <Modal
              aria-labelledby="transition-modal-title"
              aria-describedby="transition-modal-description"
              className={'modalbox'}
              open={this.state.open}
              onClose={this.handleClose}
              closeAfterTransition
              BackdropComponent={Backdrop}
              BackdropProps={{
                timeout: 500,
              }}
            >
              <Fade in={this.state.open}>
                <div className={'modalboxform ' + this.props.classes}>
                  <IconButton className="close-button" onClick= 
                      {this.handleClose}>
                    <CloseIcon/>
                  </IconButton>
                  {this.props.modalContents}
                </div>
              </Fade>
            </Modal>
          </>
        );
    }
}

  class extend home Component{
   render(){
     return(
      <ModalBox 
    button={{"label": "Log In", "color":"primary"}}
     modalContents={
       <div className="login-form">
       <Grid container spacing={1}>
         <Grid item xs={12} sm={12}>
          <GenericForm 
            initialValues={initialLoginFormValues} 
            fields={fieldsLoginForm}
            buttons={buttonsLoginForm}
            submitHandler={this.loginFormHandler}
          />

          {errorMsg.length > 0 && 
            (
              <div className="error-text">
                {errorMsg}
              </div>
            )
          }

        </Grid>
        <Grid item xs={12} sm={12}>
          <div className="forgot-password-pane">
            <NavLink
              to="/forgotpassword"
              activeClassName="selected"
              onClick={this.handleClose}
              >Forgot password?
            </NavLink>
          </div>
        </Grid>
        <Grid item xs={12} sm={12}>
          Don't have an account? Don't worry, you can <NavLink to="/" 
       activeClassName="selected">join here</NavLink>
        </Grid>
      </Grid>
    </div>
  
     />
  )
   }
 }


整个代码在一个文件中,这是我看到的唯一解决方案,无需使用 redux 或 context api 之类的东西


推荐阅读