Issue with Modal component: Unable to successfully implement a condition using a prop in the component

Currently, I am working on creating a Modal that should disable the scrollbar when opened. However, I am facing an issue where the scrollbar remains even after opening the Modal.

The Modal component is structured within a component and I am unable to pass the 'open' prop to the condition. This results in the scrollbar staying visible despite attempting to open the Modal.

In my Dialog.js file, I have defined an array and functions which are passed as props to other components like individual Modals.

Dialog.js

export default function Dialog() {
  let [Dentistry, setDentistry] = useState(false);
  let [Endodontics, setEndodontics] = useState(false);
  let [Orthodontics, setOrthodontics] = useState(false);

  const specializationsData = [
    {
      setOpen: setDentistry,
      open: Dentistry,
    },
    {
  
      setOpen: setEndodontics,
      open: Endodontics,   
    },
    {
      id: 3,
      setOpen: setOrthodontics,
      open: Orthodontics,
    },
  ];

  return (
    <>
          <div className="grid gap-8 mx-auto md:grid-cols-3">
            {specializationsData.map((item) => {
              return (
                <>
                  <Card setOpen={item.setOpen}>
                    <CardTitle>{item.title}</CardTitle>
                    <CardDescription>{item.text}</CardDescription>
                  </Card>

                  <Modal setOpen={item.setOpen} open={item.open}>
                    <ModalTitle>{item.title}</ModalTitle>
                    <ModalDescription>
{item}
                    </ModalDescription>
                  </Modal>
                </>
              );
            })}
          </div>
    </>
  );
}

Utilizing the Card component helps trigger the opening of the Modal successfully by passing the 'setOpen' prop from Dialog.js.

Card.js

export function Card({ setOpen, children }) {
  return (
    <>
      <div
        onClick={() => setOpen(true)}
        className="px-4 py-6 text-center rounded-lg cursor-pointer select-none bg-gradient-to-br from-white to-neutral-50 drop-shadow-lg"
      >
        {children}
      </div>
    </>
  );
}

On the contrary, there seems to be an issue with the 'open' prop not functioning correctly to hide the scrollbar when the Modal is open.

Modal.js

export function Modal({ open, setOpen, children }) {
  if (typeof document !== "undefined") {
    if (open) {
      document.body.style.overflow = "hidden";
    } else {
      document.body.style.overflow = "";
    }
  }

  return (
    <>
      <div
        className={`${open ? "" : "hidden"} fixed z-10 inset-0 overflow-y-auto`}
      >
        <div className="flex items-center justify-center min-h-screen p-4">
          <div className="fixed inset-0 bg-black opacity-30"></div>

          <div className="relative w-full max-w-2xl p-8 mx-auto bg-white rounded-lg">
            {children}
          </div>
        </div>
      </div>
    </>
  );
}

Answer №1

If you want to keep track of open states, consider using the useEffect hook in your code. Here's a helpful resource on how to use it: https://reactjs.org/docs/hooks-effect.html

const [modalIsOpen, setmodalIsOpen] = useState(open);

  useEffect(() => {
    // Update the body style when the modalIsOpenState changes
    if (modalIsOpen) {
      document.body.style.overflow = "hidden";
    } else {
      document.body.style.overflow = "";
    }
  }, [modalIsOpen]); // adding this will run useEffect any time modalIsOpen changes see the "Tip: Optimizing Performance by Skipping Effects" part of the documentation for more details

Although your question is about next.js, I mainly work with React. However, you can still apply my solution in your Next.js application by importing useEffect like this:

import React, { useState, useEffect } from 'react'

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

PhantomJS is failing to provide any output

Currently, I am utilizing PhantomJS for web scraping purposes. However, I have encountered an issue where the evaluate method is not returning any data. The script seems to run for a few seconds and then unexpectedly exits. I have confirmed that PhantomJS ...

The text/font-weight of the header button is mysteriously shifting without warning

While creating a header for my webpage, I encountered an issue where the text family was changing when the dropdown menu was launched in Safari 8. Curiously, this behavior did not occur when using Chrome to launch the jQuery function. Even after attempting ...

I could see the Javascript and CSS code manifesting directly onto my HTML page

I've encountered a strange issue with my calendar code where my JavaScript and CSS codes are inexplicably showing up next to the calendar. Does anyone have any insights into why this may be happening? I developed the code in an online HTML/CSS/JS edit ...

What is the method for accessing a selector within a foreach loop?

Whenever a user clicks on a date in the jquery datepicker, two ajax calls are triggered. The goal is for the second ajax call to populate the response/data into a paragraph with the class spots within the first ajax call, displaying available spots for th ...

Attempting to extract solely the animated elements from a GLTF file

Is there a way to extract only the animations from a gltfAsset in order to create an animation file? I'm wondering if there is a library or an easier method to accomplish this task. private async createAnimationAssets(props: Props, animations: Animati ...

What is the best way to modify the values in an initialized array once the fetchData method has been executed?

As a beginner in Vue.js, I am currently working on a project that involves updating initialized arrays in the data() section of my component using the fetchData method. Below is a simplified version of the code: <script> import axios from 'axi ...

Converting Decimal to RGB Values using JavaScript and PHP

Seeking assistance with converting a decimal value to an RGB value. Here is the formula I am using to compile the decimal value: c = r*(255*255)+g*255+b For instance, rgb(16,120,78) results in 1071078. What is the best way to solve for r, g, and b with ...

Understanding Variables in Javascript Tutorial

After diving into the tutorials here, I find myself struggling to grasp some elements of this example. Why is the variable initialized as an empty string and what does the ,i signify? var x="",i; Furthermore, why the need for x=x at the start of the l ...

Update the JSON by replacing any null values with a predefined string

When working with JSON data, I often come across empty values that I need to replace with a default string. var jsonData= [ { "machineNum": "1A", "serialNo": "123", "city": "" }, { "machineNum": "2B", "serialNo": "", "city": "" }, ...

Execute a parent action within a Controller

I'm currently working on customizing the update() and create() actions within a specific controller in my Sails.js application. My goal is to upload a file first, store the file path (which is saved on s3 using skipper) in the request body, and then ...

Load a partial view in MVC using Ajax with a complex data structure

Within my main view, I have a section that loads a partial view containing data. Here is the code snippet that is executed upon initial loading: <div id="customerdetailsDIV" class="well main-well clearfix"> @Html.Partial("_customer_details", Mod ...

Utilizing the power of AngularJS in conjunction with requireJS

Currently, I am diving into a tutorial on the integration of AngularJS with RequireJs. However, I am finding it challenging to grasp the concept. In the tutorial, the author introduces a file named app.js and includes the following code snippet; define(f ...

How can I programmatically control the scrollbar of an iframe displaying a PDF using JavaScript?

As I explore ways to display PDF documents on a Smart TV, I have decided to implement invisible buttons for scrolling up and down the document. This functionality needs to be integrated into a web environment, so this is what I have attempted: Here is the ...

The latest version is available, but remember to update @react-navigation/bottom-tabs, @react-navigation/stack, and @react-navigation/drawer to at least version 5.10.0

As a newcomer to react-native, I am currently attempting to execute a program using expo but encountering a yellow error message. The error states: 'It seems that you are utilizing an outdated version of the react-navigation library. Please ensure th ...

View the gathered HTML content in a fresh browser tab

I'm looking to enhance the reporting system on my website by sending an AJAX request with a progress bar. The server will collect the necessary data, convert it into HTML, and then send it back to me. Upon successful completion of the AJAX request, I ...

What is the most efficient way to organize information in the Firebase real-time database?

I'm having a tough time sorting data in the real-time database. I've been following the documentation and implementing the steps exactly, but so far, nothing seems to be working. I expected it to work similarly to filtering, which is functioning ...

How to Trigger a Child Component Function from a Parent Component in React.js

I want to trigger a function in my child component when a button is clicked in the parent component. Parent Component: class Parent extends Component{ constructor(props){ super(props); this.state = { //.. } } ...

Vue - Utilizing child slots in the render method

Within my component, I am working with a default slot and attempting to enhance the layout by wrapping each item in the slot within a div. However, I am facing an issue where I need to retrieve the classes of one of the slot elements, but the VNode element ...

How can I retrieve the current quarter, as well as the three preceding quarters, including the corresponding year, using Moment.js

Could you provide a method for retrieving the current quarter and the previous three quarters in conjunction with the year? For instance, it should output four quarters as follows: q3-2016 q2-2016 q1-2016 q4-2015 ...

Duplicating an element in an array using JavaScript

My view model is structured as follows public class ItemViewModel { [Required] public int Id { get; set; } [Required] public int JobId { get; set; } public string ItemId { get; set; } public string ItemN ...