简体   繁体   中英

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

There's a button overlayed on a page, and once the button is pressed, the page is supposed to be dimmed and a modal popup shows up.

However, for my code, the popup just shows up but the background page isn't affected whatsoever. The modal opens and closes correctly, however.

Code for the button:

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

Code for the modal:

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

Relevant code for the page the button is on:

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

I know I'm definitely not taking into consideration the right styling rules, and also what to do about altering the Page class once the MessageBrokerButton is clicked. But I'm not exactly sure which parts to change and what I should be changing.

There are multiple ways of doing this. What you could do is create a new Shadow-component that is a child of Page (or whatever is your actual root component). This Shadow is then given a state prop that tells the component whether to render the shadow-div or not.

All this is pretty easy. The most complex part is usually to come up with some sensible state management system so that you can trigger the Shadow without passing the "enable shadow" handler all around. I suggest to check out Redux for this.

Use z-index style to make sure the shadow appears between the Page and the modal. For Example shadow z-index 1, modal container 2. Also, make sure both shadow and the modal container are positioned as absolute as they both should overlay the page.

Here's a pseudo-simplification:

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

Now you just use the this.props.handleHasShadow(true/false) function to enable/disable the shadow. The shadow will be as big as the parent (Page) component.

You may also want to make sure that the focus stays inside your modal. Otherwise users will be able to tab-out from the modal. Keyword here is focus-trap.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM