模态弹出窗口无法正常工作(希望背景页面变暗)

Modal pop-up not working properly (want the background page to dim)

有一个按钮覆盖在页面上,按下按钮后,页面应该变暗并显示模式弹出窗口。

然而,对于我的代码,弹出窗口只是显示,但背景页面没有受到任何影响。然而,模式打开和关闭正确。

按钮代码:

class MessageBrokerButton extends Component {
    constructor(props) {
        super(props)
        this.state = {
            isShowing: false
        }
    }

    openModalHandler = (e) => {
        this.setState({
            isShowing: true
        });
        e.preventDefault();
    }

    closeModalHandler = () => {
        this.setState({
            isShowing: false
        });
    }

    render() {
        return (
            <div>
                <button className='message-broker' onClick={this.openModalHandler}>
                    Message Broker
                </button>
                <div className='message-icon'></div>

                { this.state.isShowing ?         
                    <Popup 
                        show={this.state.isShowing} 
                        close={this.closeModalHandler}>
                            Test
                    </Popup> 
                    : null 
                }
            </div>
        )
    }
}

模态代码:

const Popup = (props) => {
    return (
        <div>
            <button onClick={props.close}>CLOSE</button>
            <p> {props.children}</p>
        </div>
    )
}

按钮所在页面的相关代码:

class Page extends Component {
    constructor(props) {
        super(props);
        this.state = {

        };
    };

    render() {
        let page100 = 
        <div>
            <MessageBrokerButton></MessageBrokerButton>
        </div>

        if (this.props.currentPage !== this.state.page) {
            page100 = null;
        }

        return (
        <form onSubmit={this.handleFormSubmit}>

            {page100}

        </form>
        );
    }
}

我知道我绝对没有考虑正确的样式规则,也没有考虑单击 MessageBrokerButton 后如何更改页面 class。但是我不确定要更改哪些部分以及我应该更改什么。

有多种方法可以做到这一点。您可以做的是创建一个新的 Shadow-component,它是 Page 的子组件(或者您的实际根组件)。然后给这个 Shadow 一个 state 属性,告诉组件是否渲染阴影 -div 或不。

这一切都非常简单。最复杂的部分通常是想出一些合理的状态管理系统,这样你就可以在不传递 "enable shadow" 处理程序的情况下触发 Shadow。我建议检查一下 Redux。

使用 z-index 样式确保阴影出现在页面和模式之间。例如阴影 z-index 1,模态容器 2。此外,请确保阴影和模态容器都定位为绝对位置,因为它们都应覆盖页面。

这是一个伪简化:

class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      hasShadow: false,
      modal: null, // Modal can be a React-component, like the Popup.
    };
  }
  handleHasShadow = hasShadow => {
    this.setState({ hasShadow });
  }
  handleSetModal = modal => {
    this.setState({ modal });
  }
  render() {
    return (
      <div>
        <form ...>
          {
            this.props.currentPage === this.state.page
              ? <MessageBrokerButton handleHasShadow={this.handleHasShadow} />
              : null
          }
        </form>
        <Shadow isEnabled={this.state.hasShadow} />
        {/* You can give modal as a prop too! */}
        <ModalContainer>{modal}</ModalContainer>
      </div>
    );
  }
}

Shadow.jsx

const Shadow = ({ isEnabled }) => {
  return isEnabled ? (
    <div
      style={{
        position: 'absolute',
        top: 0,
        right: 0,
        bottom: 0,
        left: 0,
        background: '#000000',
        opacity: 0.5,
        zIndex: 1,
      }}
    />
  ) : null;
}

现在您只需使用 this.props.handleHasShadow(true/false) 函数来 enable/disable 阴影。阴影将与父(页面)组件一样大。

您可能还想确保焦点停留在模态框内。否则用户将能够从模式中退出。这里的关键词是 focus-trap.