Links and buttons unresponsive in React modal window

My current challenge involves utilizing ReactDOM.createPortal to create a global modal that can be accessed from any page within the React app. The modal opens and displays correctly, but I have encountered an issue where the and elements inside the modal are unresponsive to clicks.

The problem is not related to the onClick functions not working; rather, it seems that these elements cannot be clicked on at all. Neither the anchor nor the button reacts when attempting to interact with them. Despite rendering as expected, both elements fail to respond to mouse clicks. Ideally, either the anchor or the button should serve to close the modal.

https://i.stack.imgur.com/srLrX.png

Since I was unable to make the anchor or button clickable, I attempted to attach a click event to the overlay div positioned behind the modal dialog div, effectively covering the rest of the page. While this solution technically works, it proves impractical as clicking anywhere within the modal dialog triggers the same click event.

Modal.tsx

import ReactDOM from "react-dom";
import './Modal.css';
export default function Modal(props:any){
    const handleCloseClick = () => {
        props.onClose();
    };

    const modalContent = (
        <div className="modal-overlay" onClick={handleCloseClick}>
            <div className="modal-dialog">
                <div className="modal-header d-flex justify-content-between">
                    <span>{props.title}</span>
                    <a href="#" onClick={handleCloseClick}>X</a>
                </div>
                <div className="modal-body">
                    <p>Modal content goes here</p>
                    <button>TEST</button>
                </div>
            </div>
        </div>
    )

    return ReactDOM.createPortal(modalContent, document.body as Element);
}

Modal.css

.modal-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: rgba(0, 0, 0, 0.5);
    z-index: 99;
}

.modal-dialog {
    width: 500px;
    height: 300px;
    background-color: white;
    z-index: 100;
}

.modal-body {
    padding-top: 10px;
}

.modal-header {
    display: flex;
    justify-content: flex-end;
    font-size: 25px;
}

RootLayout.tsx contains the 'Open Modal' button along with the management of the modal's visibility state.

import { Link, Outlet } from 'react-router-dom';
import { useAuth, UseLogin, UseLogout } from '../authentication.context';
import Login from './Login';
import './RootLayout.css';
import { useEffect, useState } from 'react';
import Modal from './Modal';
export default function RootLayout(props: any) {
    const { state, dispatch } = useAuth();
    const [modalVisible, setModalVisible] = useState(false);

    const handleLogout = () => {
        const actions = UseLogout();
        dispatch(actions);
    }

    useEffect(() => {
        if (state) {
            console.log('state in RootLayout:');
            console.log(state);
        }
    }, [state]);

    if (state && state.isAuthenticated) {
        return (
            <div className='h-100'>
                <nav className='navbar navbar-expand-md border border-bottom'>
                    <div className='container-fluid'>
                        <a className="navbar-brand" href="#">JOC Dashboard</a>
                        <button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="SupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                            <span className="navbar-toggler-icon"></span>
                        </button>
                        <div className="collapse navbar-collapse" id="navbarSupportedContent">
                            <ul className="navbar-nav me-auto mb-2 mb-lg-0">
                                <li className="nav-item">
                                    <Link className='nav-link active' to="/">Home</Link>
                                </li>
                            </ul>

                            <div className='d-flex justify-content-between align-items-center'>
                                {state.user &&
                                    <div className='me-3'>Logged in as {state.user.full_name}</div>
                                }

                                <div className=''>
                                    <button className='btn btn-primary' onClick={handleLogout}>LOGOUT</button>
                                </div>
                            </div>
                        </div>
                    </div>
                </nav>
                <div id="root-layout-container" className='container-fluid'>
                    <div className='row'>
                        <div className='col-lg-2'>
                            <div className='d-flex flex-column'>
                                <button onClick={() => setModalVisible(true)}>Open Modal</button>
                            </div>  
                        </div>
                        <div className='col-lg-10'>
                            <Outlet/>
                        </div>
                    </div>
                </div>
                {modalVisible &&
                    <Modal title="Title" onClose={() => setModalVisible(false)}/>
                }
            </div>
            
                
        )
    }

    return (
        <div id="root-layout-container" className='container-fluid h-100'>
            {state && !state.isAuthenticated &&
                <Login />
            }
        </div>
    )
}

I've thoroughly checked the z-index values for each modal div and found no overlaps obstructing the anchor or button elements. However, despite my efforts, these components remain unclickable. Can you suggest other factors that may be preventing these elements from being interactive?

Answer №1

It turns out that the issue was with the class names I had chosen to use. It seems like some of them were conflicting with class names from other dependencies, possibly because this app is built on Bootstrap 5. Fortunately, making a simple adjustment by changing the following class names resolved the problem:

  • .modal-overlay
  • .modal-dialog
  • .modal-header
  • .modal-body

I updated these class names to be:

  • .main-modal__overlay
  • .main-modal__dialog
  • .main-modal__header
  • .main-modal__body

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

Encountered an unidentified state with React context

I am new to integrating Reactjs with Laravel. I'm facing an issue where the context is returning as undefined when trying to send data between components. Specifically, I want to pass data from Product_Detail.js to Cart.js globalContext.js import Rea ...

Ensure data accuracy by triggering the cache - implementing SWR hook in Next.js with TypeScript

I recently implemented the swr hook in my next.js app to take advantage of its caching and real-time updates, which has been incredibly beneficial for my project (a Facebook clone). However, I encountered a challenge. The issue arises when fetching public ...

What is the best way to determine the current vertical scroll position in JavaScript?

Take a look at this: const handleScroll = () => { console.log(window.scrollY) }; useEffect(() => { window.addEventListener("scroll", handleScroll); return () => window.removeEventListener("scroll", handleScroll); }); ...

Delay the rendering of the fetching component until the fetch operation is completed

My task is to retrieve data for SSR and send that data from the Client. const MyPage = ({ myFetch1, myFetch2, myFetch3, }) => { const dispatch = useDispatch(); dispatch(doSomething1(myFetch1)); dispatch(doSomething2(myFetch2)); dispatch(do ...

ExceptionError: Unable to access the startsWith property of an undefined value

import React from 'react'; import AttributeDescription from './AttributeDescription'; class CompEntry extends React.Component{ render(){ let modifiedDescription; if(this.props.description.startsWith("_")){ modifiedD ...

Unable to differentiate between .jsx and .js files

Here is the content of my JavaScript file: var React = require('react'); export default class AmortizationChart extends React.Component { render() { var items = this.props.data.map(function (year, index) { ret ...

Improving conditional rendering in Mui <Cards> component by fixing state behavior

I have a situation where I want to display a Floating Action Button inside each Mui card when hovered over. However, I'm running into an issue with the hover state affecting all cards instead of just the one being interacted with. How can I ensure tha ...

Encountering problems with `npm run build` when using `con

Running a react app with express as the backend has been quite the adventure. After following this particular tutorial on how to connect the two and deploy to heroku, I found myself in a bit of a conundrum. Express is running smoothly on port 5000 as instr ...

Switch between MMM dd yyy and dd/mm/yyyy date formats easily

I have implemented a native material-ui date picker which currently displays dates in the dd/mm/yyy format. However, I need to customize the display format to show dates like this: Jun 18 2012 12:00AM. This specific date format is essential for consistency ...

Implement a basic authentication system in a React application without relying on an actual backend server

I'm currently navigating through this tutorial and attempting to comprehend its content. I've hit a roadblock when it comes to token authentication due to the lack of an API. The tutorial recommends using this piece of code within the Login comp ...

Error on Heroku: E316 - the journey of a thousand unknowns begins with a

Trying to deploy my MERN stack app on Heroku, it's working fine on localhost but encountering an H10 error while following the Heroku deployment steps. It seems like I'm missing something trivial, and I've hit a dead end. I've checked t ...

Deactivate a button whenever there is a change in the user's state

In order to manage the user status in the database, I am utilizing a field called isActive that can have a value of true or false. On the user interface, there are two buttons - the green button activates the user upon clicking, while the red button deact ...

What is the best way to organize notifications by dates in a React application?

I'm currently working on a notifications component where I need to sort notifications by dates and then display them. Although I attempted the following code, it didn't work as intended: const result = notifications.notificationRows.sort((a, b) ...

The NextJS routing feature displays the [slug] parameter in the URL

I am encountering an issue with my NextJS app's folder structure: - pages - docs - [slug] - index - [id] - index These pages are intended to be dynamic, displaying data dynamically on the UI. This means that users can navigate t ...

Utilizing JSON data within an href tag in React applications

In the process of retrieving data, I have a JSON object. Here is an example of the JSON structure: { "postid": "123123", "title": "title of post" } I am attempting to include this post ID within an href tag like <a href="https:/ ...

Attempting to modify the state within the useEffect() hook results in the error message "Unable to update a React state on an unmounted component."

I am working on a material drawer component that, upon mounting, needs to access the local storage to retrieve the logged-in user's information and display their name in the template. Below is the code for my component: const PersistentDrawer = () = ...

The React data editor Dialog closes when the drop-down is clicked without triggering any onChange events

Utilizing the react-datasheet component, I have implemented a table to display a matrix/grid of data. To enhance user experience, I customized the dataEditor to launch a custom dialog where users can only choose from preselected values in a material-ui dro ...

Obtain access to global.window.localStorage within getServerSideProps

I have a component that receives props with data and renders the data. In my functionality within the getServerSideProps, I am attempting to retrieve data from localStorage. However, due to window being undefined, I am unable to do so. I have tried using ...

Tips for fixing label overlap problem in React Material UI autocomplete component

I recently started working with React Material UI and I am looking to implement a floating label for the auto complete component. However, once a value is selected from the auto complete options, I want the label to stay at the top. For further clarifica ...

The swipe motion will be executed two times

By pressing the Circle button, the Box will shift to the right and vanish from view. Further details (FW/tool version, etc.) react scss Typescript framer-motion import "./style.scss"; import React, { FunctionComponent, useState } from &q ...