'My custom modal doesn't close because of react's useState hook

My custom modal window opens up but doesn't close when I click on the darkened area. I investigated a bit and found out that the setActive function in the modal component doesn't set the active to false for some reason. How can I fix this?

The modal file

import React from 'react'
import './style.css'


const Modal = ({active, setActive, children}) => {

  return (
    <div className={active?'modal_main active':'modal_main'} onClick={()=>{setActive(false)}}>
        <div className={active?'modal_content active':'modal_content'} onClick={e=>e.stopPropagation()}>
           {children}
        </div>
    </div>
  )
}

export default Modal

Where I use the modal window

import React, { useState } from 'react'
import Modal from '../../modal'
import './style.css'

function TagItem(props) {
  const [tagActive, setTagActive] = useState(false);

  return (
    <div className='tag-item' onClick={()=>setTagActive(true)}>
      {props.tag}
      <Modal active = {tagActive} setActive = {setTagActive}>
        <div >{props.tag}</div>
      </Modal>
    </div>
  )
}

export default TagItem

modal's css

.modal_main{
    width: 100vw;
    height: 100vh;
    background-color: rgba(0, 0, 0, 0.4);
    position: fixed;
    top: 0;
    left: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    pointer-events: none;
    transition: 0.5s;
    z-index:1;
}

.modal_main.active{
    opacity: 1;
    pointer-events: all;
}

.modal_content{
    padding: 20px;
    border-radius: 12px;
    background-color: white;
    height: fit-content;
    width: fit-content;
    transform: scale(0.5);
    transition: 0.4s all;
}

.modal_content.active{
    transform: scale(1);
}

tag-item's css

.tag-item{
    border: 1px limegreen solid;
    border-radius: 8px;
    background-color: rgb(178, 246, 119);
    width: fit-content;
    padding: 2px;
    margin: 2px;
    cursor: default;
}

.tag-item:hover{
    cursor: default;
    background-color: rgb(1, 152, 1) ;
}


Solution 1:[1]

Issue

The click event from the modals's outer div elementis triggering the state update, but it's also propagated out of theModalcomponent to theTagItemcomponent'sdivelement and this enqueues atagActivestate update totrue`. The state update to close the modal is overwritten.

Solution

Stop the propagation of the outer div element's click event.

const Modal = ({ active, setActive, children }) => {
  return (
    <div
      className={active ? "modal_main active" : "modal_main"}
      onClick={(e) => {
        e.stopPropagation(); // <-- stop propagation to parent component
        setActive(false);
      }}
    >
      <div
        className={active ? "modal_content active" : "modal_content"}
        onClick={(e) => {
          e.stopPropagation();
        }}
      >
        {children}
      </div>
    </div>
  );
};

Edit my-custom-modal-doesnt-close-because-of-reacts-usestate-hook

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Drew Reese