Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

popup modal in react

How to Make Popup Modal in React

In this article, we will make popup modal in react. This modal will be look like any advertisement popping up on the screen, but we will do this when we click a button. We will also add some animations when it gets popped up and add three ways to close this modal. We can close it by using close button which will be in the modal, next we will close it by clicking the background and lastly, we can do the same using escape button.

This will be a very basic project, but it will be very useful at the same time. So let’s just make it step by step.

Setting up Dependencies

So first thing first, is to set up dependencies and installing required packages. Here we will install the styled-componets package, so with this we can actually style the JSX inside the React components. For simplicity, you can say it allows us to add basic internal CSS, here you can’t add advanced CSS like animations, transitions etc. You can install it with below line of command.

npm install styled-components

Next, we will install react-spring a package, so with this we can add some animations to our components. Since we need some animations to our modal, then we need this package.

npm install react-spring

Lastly, we need to install react-icons, as it name suggests that we can add icons using this package, Here we will add cross icon as our close button.

npm install react-icons

Adding Initial Button

In App.js file, we are adding the button for modal, As we can see in below code we have imported all required packages like react, styled-components, we have also added a file named Modal.js, in this file we will add modal. Also, we have added a GlobalStyles.js file, in which we will add some basic styles for global elements.

Then here we can see that we have added some constants like Container, Button, in which we have added styled.div``. This is the basic syntax when we want to use styled-components for <div>, in this we have applied some basic CSS styles. These constants can be accessed like components, So if we want to use Container, then we can use <Container>. Here in styled.div, div specifies the element, if we want to add a button then we can write styled.button.

So here, we have applied some CSS styling for the elements like <div>, and <button>. Now we want to define openModal() function, for this we have added the useState hook, and its value will be false by default. Then in the function, we are just setting the value for state from false to true. Then we are just adding <Modal> with showModal and setShowModal as props. Lastly, we have just added <GlobalStyle> from globalStyles file, in which we have just added a little bit CSS for global elements.

App.js

import React, { useState } from 'react';
import styled from 'styled-components';
import { Modal } from './components/Modal';
import { GlobalStyle } from './globalStyles';

const Container = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
`;

const Button = styled.button`
  min-width: 100px;
  padding: 16px 32px;
  border-radius: 4px;
  border: none;
  background: #141414;
  color: #fff;
  font-size: 24px;
  cursor: pointer;
`;

function App() {
  const [showModal, setShowModal] = useState(false);

  const openModal = () => {
    setShowModal(showModal => !showModal);
  };

  return (
    <>
      <Container>
        <Button onClick={openModal}>I'm a modal</Button>
        <Modal showModal={showModal} setShowModal={setShowModal} />
        <GlobalStyle />
      </Container>
    </>
  );
}

export default App;
popup modal in react

Creating Modal Element

Now let’s make the modal, in this we have added all kind of packages, Then let’s jump directly to the return(), in this we have added {showModal} to check where it is true or false. If it is true, then we called <background> in which we have added an onClick listener with closeModal function. In this function, we have we check condition where modelRef.current === e.target, if it is same, then we update the hook with false.

Then we have added animation on the modal div with <animated.div>, we added some duration with certain duration, we also check showModal value if true then we add opacity to 1 and also added translateY to 0. Otherwise, we just add 0 opacity and -100% translateY.

After that, we will add the modal in showModal, in this we added an image here, also we have added some random text as content. Now on close button, we have added onClick listener, on which we have added again showModel value from true to false. We again added some basic styling on these components using styled-components package.

By doing these many things, we are able to see the modal after the button gets clicked, and get closed if the close button gets hit. Now we need to add functionality to close the modal while clicking background and escape button. For Escape button, we have added a callback function, in this we are checking the e.key with escape if it is matched then we update the setShowModal with false value. For Background, we have added an event listener to listen “keydown”, here we also use Keypress function again because we already wrote the logic to remove the Modal, so we just need to call this function here as well.

import React, { useRef, useEffect, useCallback } from 'react';
import { useSpring, animated } from 'react-spring';
import styled from 'styled-components';
import { MdClose } from 'react-icons/md';

const Background = styled.div`
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.8);
  position: fixed;
  display: flex;
  justify-content: center;
  align-items: center;
`;

const ModalWrapper = styled.div`
  width: 800px;
  height: 500px;
  box-shadow: 0 5px 16px rgba(0, 0, 0, 0.2);
  background: #fff;
  color: #000;
  display: grid;
  grid-template-columns: 1fr 1fr;
  position: relative;
  z-index: 10;
  border-radius: 10px;
`;

const ModalImg = styled.img`
  width: 100%;
  height: 100%;
  border-radius: 10px 0 0 10px;
  background: #000;
`;

const ModalContent = styled.div`
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  line-height: 1.8;
  color: #141414;

  p {
    margin-bottom: 1rem;
  }

  button {
    padding: 10px 24px;
    background: #141414;
    color: #fff;
    border: none;
  }
`;

const CloseModalButton = styled(MdClose)`
  cursor: pointer;
  position: absolute;
  top: 20px;
  right: 20px;
  width: 32px;
  height: 32px;
  padding: 0;
  z-index: 10;
`;


export const Modal = ({ showModal, setShowModal }) => {
  const modalRef = useRef();

  const animation = useSpring({
    config: {
      duration: 250
    },
    opacity: showModal ? 1 : 0,
    transform: showModal ? `translateY(0%)` : `translateY(-100%)`
  });

  const closeModal = e => {
    if (modalRef.current === e.target) {
      setShowModal(false);
    }
  };

  const keyPress = useCallback(
    e => {
      if (e.key === 'Escape' && showModal) {
        setShowModal(false);
        console.log('I pressed');
      }
    },
    [setShowModal, showModal]
  );

  useEffect(
    () => {
      document.addEventListener('keydown', keyPress);
      return () => document.removeEventListener('keydown', keyPress);
    },
    [keyPress]
  );

  return (
    <>
      {showModal ? (
        <Background onClick={closeModal} ref={modalRef}>
          <animated.div style={animation}>
            <ModalWrapper showModal={showModal}>
              <ModalImg src={require('./modal.jpg')} alt='camera' />
              <ModalContent>
                <h1>Are you ready?</h1>
                <p>Get exclusive access to our next launch.</p>
                <button>Join Now</button>
              </ModalContent>
              <CloseModalButton
                aria-label='Close modal'
                onClick={() => setShowModal(prev => !prev)}
              />
            </ModalWrapper>
          </animated.div>
        </Background>
      ) : null}
    </>
  );
};
popup modal in react

Full Source Code to Make Popup Modal in React

App.js

import React, { useState } from 'react';
import styled from 'styled-components';
import { Modal } from './components/Modal';
import { GlobalStyle } from './globalStyles';

const Container = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
`;

const Button = styled.button`
  min-width: 100px;
  padding: 16px 32px;
  border-radius: 4px;
  border: none;
  background: #141414;
  color: #fff;
  font-size: 24px;
  cursor: pointer;
`;

function App() {
  const [showModal, setShowModal] = useState(false);

  const openModal = () => {
    setShowModal(showModal=>!showModal);
  };

  return (
    <>
      <Container>
        <Button onClick={openModal}>I'm a modal</Button>
        <Modal showModal={showModal} setShowModal={setShowModal} />
        <GlobalStyle />
      </Container>
    </>
  );
}

export default App;

Modal.js

import React, { useRef, useEffect, useCallback } from 'react';
import { useSpring, animated } from 'react-spring';
import styled from 'styled-components';
import { MdClose } from 'react-icons/md';

const Background = styled.div`
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.8);
  position: fixed;
  display: flex;
  justify-content: center;
  align-items: center;
`;

const ModalWrapper = styled.div`
  width: 800px;
  height: 500px;
  box-shadow: 0 5px 16px rgba(0, 0, 0, 0.2);
  background: #fff;
  color: #000;
  display: grid;
  grid-template-columns: 1fr 1fr;
  position: relative;
  z-index: 10;
  border-radius: 10px;
`;

const ModalImg = styled.img`
  width: 100%;
  height: 100%;
  border-radius: 10px 0 0 10px;
  background: #000;
`;

const ModalContent = styled.div`
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  line-height: 1.8;
  color: #141414;

  p {
    margin-bottom: 1rem;
  }

  button {
    padding: 10px 24px;
    background: #141414;
    color: #fff;
    border: none;
  }
`;

const CloseModalButton = styled(MdClose)`
  cursor: pointer;
  position: absolute;
  top: 20px;
  right: 20px;
  width: 32px;
  height: 32px;
  padding: 0;
  z-index: 10;
`;

export const Modal = ({ showModal, setShowModal }) => {
  const modalRef = useRef();

  const animation = useSpring({
    config: {
      duration: 250
    },
    opacity: showModal ? 1 : 0,
    transform: showModal ? `translateY(0%)` : `translateY(-100%)`
  });

  const closeModal = e => {
    if (modalRef.current === e.target) {
      setShowModal(false);
    }
  };

  const keyPress = useCallback(
    e => {
      if (e.key === 'Escape' && showModal) {
        setShowModal(false);
        console.log('I pressed');
      }
    },
    [setShowModal, showModal]
  );

  useEffect(
    () => {
      document.addEventListener('keydown', keyPress);
      return () => document.removeEventListener('keydown', keyPress);
    },
    [keyPress]
  );

  return (
    <>
      {showModal ? (
        <Background onClick={closeModal} ref={modalRef}>
          <animated.div style={animation}>
            <ModalWrapper showModal={showModal}>
              <ModalImg src={require('./modal.jpg')} alt='camera' />
              <ModalContent>
                <h1>Are you ready?</h1>
                <p>Get exclusive access to our next launch.</p>
                <button>Join Now</button>
              </ModalContent>
              <CloseModalButton
                aria-label='Close modal'
                onClick={() => setShowModal(prev => !prev)}
              />
            </ModalWrapper>
          </animated.div>
        </Background>
      ) : null}
    </>
  );
};

Output

popup modal in react

Check out video reference here:

You may also like:

Default image
reactjsguru
Articles: 44

Leave a Reply

Your email address will not be published.