The React modal window stubbornly refuses to close

import c from '../Profile.module.css'; 
import { useState } from 'react';
import { createPortal } from 'react-dom';

import Modal from '../Modal/Modal';

const TransactionItem = (props) => {
    const modalRoot = document.querySelector('#root > div');
    const [showModal, setShowModal] = useState(false);
    const short = str => str.substring(str.length - 4) + '...' + str.substring(0, 5);
    
    const handleClose = () => {
        setShowModal(false);
    }

    return (
        <div className={c.transaction_item} onClick={() => setShowModal(true)}>
            <div className={c.transaсtion_data}>
                <div className={c.icon}><span>$</span></div>
                <div className={c.transaction_info}>
                    {props.type === "+" ? 'Пополнение' : 'Перевод'}
                    <div className={c.transaction_where}>{short(props.from)} -&gt; {short(props.to)}</div>
                </div>
            </div>
            <span className={c.transaction_total}>{props.type + props.total}</span>
            {showModal && createPortal(
                <Modal onClose={handleClose} date='23.05.2024 в 09:41' {...props} />,
                modalRoot
            )}
        </div>
    )
} 

export default TransactionItem;

I'm experiencing difficulty in closing the modal window as expected. However, an alternative approach that seems to work is:

const handleClose = () => {
    setTimeout(() => {
        setShowModal(false);
    }, 0)
}

The strange behavior of the modal window closure without the setTimeout workaround raises questions. Could there be any specific reasons for this and are there other solutions available?

Answer №1

The popup window is enclosed in the following container:

<div className={c.transaction_item} onClick={() => openPopup(true)}>

Presumably, when you close the popup window, a click event occurs and propagates up to the parent elements, eventually reaching this event handler.

The reason why using setTimeout works is because it delays the execution of closePopup(false) until after the click event has been fully processed. In this case, it is triggered immediately after openPopup(true), whereas without setTimeout, the order would be reversed.

Within the popup window, wherever the click event is being handled, make sure to use stopPropagation() on the event. For instance, if your code in the popup looks like this:

onClick={onDismiss}

You should update it to:

onClick={e => {
  e.stopPropagation();
  onDismiss();
}}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Improving the retrieval of API data using personalized React hooks when searching by modifying keywords

I'm just starting out with React Hooks and recently wrote a small code snippet that displays a list of courses to users. This code includes two main components, CourseList and Course, as well as a custom hook called useCourseList. Here's the code ...

Tailwind - make sure the dropdown list is always on top of all other elements

Having an issue configuring the position of a dropdown list. The objective is to ensure it stays on top of all elements, however, when inside a relative positioned element, it ends up being obscured by it. Here's an example code snippet to illustrate ...

Encountered an ERESOLVE error when attempting to install a package, unable to resolve the dependency tree

After attempting to install the necessary dependencies for my project with npm install, an error message came up that I am unable to decipher: npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: &l ...

Update the text for the filter search placeholder in the Ant Table component

Is there a way to alter the default placeholder text in the Ant Table? I've set up a functioning example in documentation but couldn't find any prop for customization besides the customized filter dropdown, which I didn't want to implement. ...

Unable to locate a specific div element using Selenium in Python, encountering a NoSuchElementException

Hello, I'm new to Python and still learning the ropes. Currently, I am attempting to locate something on a particular website. Here is what I'm looking for: <div class="price">$ 1.67<span class="discount">-19.71%&l ...

Adaptive Positioned Image Display

I currently have a Section with four blocks of content. Along the right-hand side of the screen, there are some images (as shown in this example) that I want to position absolutely. However, I am encountering an issue where these images overlap with the te ...

Issue encountered when calling theme.breakpoints.down('') function from Material UI

As a novice, I have ventured into using material UI on the front-end of my project. My aim is to achieve responsiveness by leveraging theme.breakpoints.down as indicated in the material UI documentation. However, when attempting to implement this, I encoun ...

Error: Attempting to access the 'url' property of an undefined variable, despite specifically checking for its undefined status

Within my React application, I am utilizing the following state: const [functions, setFunctions] = useState([{}]); I have created a test to check if a specific property is undefined: if (typeof functions[functionCount].url !== "undefined") { ...

Discover the Color's Value in Relation to a Different Color

When it comes to my CSS, I like to use .scss to make as many variables as possible. It's easy to create a variable for one color, like $primary-color. From there, I want to work with different shades of that color, which I can easily pinpoint using Ph ...

Resolving conflicts between Bootstrap and custom CSS transitions: A guide to identifying and fixing conflicting styles

I am currently working on implementing a custom CSS transition in my project that is based on Bootstrap 3. The setup consists of a simple flex container containing an input field and a select field. The functionality involves using jQuery to apply a .hidde ...

Tips for customizing the icons and properties of the edit and delete buttons on the editable Material-table

I am currently working with material-table and editable functionality. I have successfully added the functions "onRowUpdate" and "onRowDelete", however, I would like to customize the icons for these buttons, adjust their spacing, and change their size. I h ...

Angular's Validator directive offers powerful validation capabilities for reactive forms

Referenced from: This is the approach I have experimented with: custom-validator.directive.ts import { Directive } from '@angular/core'; import { AbstractControl, FormControl, ValidationErrors } from '@angular/forms'; @Directive({ ...

What is the best way to swap out a div element with a text area when I press a button, all

I recently used a Fiddle found at http://jsfiddle.net/GeJkU/ function divClicked() { var divHtml = $(this).html(); var editableText = $("<textarea />"); editableText.val(divHtml); $(this).replaceWith(editableText) ...

What is the correct way to format React's dispatch function in order to utilize a "then" method similar to a Promise?

I'm working on a simple app that dispatches an action upon first load to populate the store. However, I'm facing an issue with trying to run a then method on dispatch, as typescript is throwing errors. (As per redux's documentation, the ret ...

Unable to retrieve resource: the server returned a 404 (Not Found) error in a ReactJS and NodeJS application

There was an error: SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON. Additionally, the server responded with a 404 (Not Found) error when trying to load a resource. I attempted to decode it on the backend with ...

Implementing bootstrap columns while displaying individual components one after the other

Here is the html code I am currently working with: <label>Search:</label> <input type="text" id="list_search" class="form-control col-8"> <button class="btn btn-info col-2">Search</button> It's interesting to note that ...

Enhancing create-react-app to handle .mjs files using webpack

I am currently facing an issue while using the Twitch npm package from our project. When deploying via create-react-app / react-scripts, there are some problems that arise. It seems that the webpack configuration bundled with create-react-app does not sup ...

Ensuring proper alignment and dimensions of tables

It's interesting to note that one of my tables is a different size than the other. My initial question is: why is this the case? I have set the width of the <th> in the top table to 100/300/100/100/100 (=700), and in the bottom table 500/100/10 ...

JavaScript: How to Build a Digital Grocery List with Browser Storage

Struggling with a tough exercise question, I could use some help deciphering it. https://i.stack.imgur.com/V5he2.png Here is how I've started the code: <!DOCTYPE html> <html> <head> <title></title> <script> fun ...

Steps for accessing the `<img>` tag within an `<a>` tag to focus on the `<img>` element in Internet Explorer

How can I target the img tag inside an href tag to set focus on the <img> element? For example: <a href="#"><img class="img1" src="abc.png"/></a> The CSS selector a .img1:focus {} does not seem to work. I am unable to access the ...