React.js - Disable background scroll when a modal is showing

Viewed 9326

I am trying to disable the background body scroll when a modal pop up window is open. I created the Modal using React portal. The only way I can think of doing this is by giving the body an overflow-y property when the Modal is open, but am unsure how to execute this..

my Modal.js looks like this

export default function Modal({open, onClose, image, title, description}){
  if (!open) return null

  return ReactDom.createPortal(
    <>
    <div id="overlay"  />
    <div id="modal" >
      <button title={title} onClick={onClose}>close</button>
      <h3>{title}</h3>
      <img src={image} className="modal-img"/>
      {description}
    </div>
    </>,
    document.getElementById('portal')
  )
}

and the component where I am 'rendering' the model

const ProjectCardUI = (props)=>{
  const[isOpen, setIsOpen] = useState(false)

  function openModal() {
    setIsOpen(true)
      // can I set the styling for '.body' or 'html' here?
  }

  return(
    
<div className="card text-center container-fluid d-flex">
  <a className="modal-click" onClick ={openModal}>this is a link</a>
  <Modal 
    open={isOpen} 
    onClose={() => setIsOpen(false)}
    title={props.cardName} 
    image={props.imgsrc}
    description={props.cardDescription}>
  </Modal>
</div>
  )
};

any help would be great.

2 Answers

Maybe something like this:

const ProjectCardUI = (props) => {
  const [isOpen, setIsOpen] = useState(false);

  function openModal() {
    setIsOpen(true);
    // can I set the styling for '.body' or 'html' here?
  }

  useEffect(() => {
    const body = document.querySelector('body');
    body.style.overflow = isOpen ? 'hidden' : 'auto';
  }, [isOpen])

  return (
    <div className="card text-center container-fluid d-flex">
      <a className="modal-click" onClick={openModal}>
        this is a link
      </a>
      <Modal
        open={isOpen}
        onClose={() => setIsOpen(false)}
        title={props.cardName}
        image={props.imgsrc}
        description={props.cardDescription}
      ></Modal>
    </div>
  );
};

You can directly manipulate the body style via the document object.

For example:

import React from "react";
import ReactDOM from "react-dom";

export default function Test() {
  const setHidden = () => {
    console.log(document.body.style.overflow);
    if (document.body.style.overflow !== "hidden") {
      document.body.style.overflow = "hidden";
    } else {
      document.body.style.overflow = "scroll";
    }
  };

  return (
    <div>     
      <button onClick={setHidden}>Click me! </button>
      <h1>1</h1>
      <h1>2</h1>
      <h1>3</h1>
      <h1>4</h1>
      <h1>5</h1>
      <h1>6</h1>
      <h1>7</h1>
      <h1>8</h1>
      <h1>9</h1>
      <h1>10</h1>
      <h1>11</h1>
      <h1>12</h1>
      <h1>13</h1>
      <h1>14</h1>
      <h1>15</h1>
      <h1>16</h1>
    </div>
  );
}
ReactDOM.render(<Test />, document.getElementById("container"));
Related