reactjs / react-modal

Accessible modal dialog component for React
http://reactcommunity.org/react-modal
MIT License
7.34k stars 807 forks source link

Rendering multiple modals #798

Open wheredannyends opened 4 years ago

wheredannyends commented 4 years ago

Summary:

I have a grid of products, each with its own modal for quick shop functionality.

I came across this issue, that suggests to conditionally render the modal. However, I would like to have a transition on the modal and according to the documentation the close transition will not run if the modal is conditionally rendered. https://github.com/reactjs/react-modal/issues/75

Expected behavior:

One instance of ReactModalPortal rendered on page

Link to example of issue:

Here is a minimal example of the transition in effect with multiple ReactModalPortal components rendered. https://codesandbox.io/s/amazing-kalam-q4zv6?fontsize=14&hidenavigation=1&theme=dark

amille14 commented 3 years ago

Any update on this? I also ran into an issue with having multiple ReactModalPortals on the page. I was expecting a single ReactModalPortal that would get reused. Unfortunately that doesn't seem to be the case.

diasbruno commented 3 years ago

If createPortal() doesn't remove the children of the element passed to it, then it would work...

You can archive the same result by moving the modal outside of the Product. Something like this should work..

const Product = ({ item, onClick }) => (
   <button onClick={() => onClick(item)}>Open {item.title}</button>
);

const App = () => {
  const [currentProduct, setProduct] = useState(null);
  return (
    <>
      {products.map((product, index) => (
         <Product item={product} key={index}  onClick={setProduct} />
      ))}
      <Modal
        closeTimeoutMS={300}
        isOpen={Boolean(currentProduct)}
        onRequestClose={() => setProduct(null)}
      >
        <button onClick={() => setProduct(null)}>Close</button>
        <h2>{currentProduct.title}</h2>
      </Modal>
    </>
  );
};
amille14 commented 3 years ago

@diasbruno since it seems that each <Modal /> component has its own ReactModalPortal div that it renders inside of, is there any easy way to get a reference to this div? My issue is that when a modal contains a dropdown menu, I need to ensure the menu element gets attached to the appropriate container element. Right now it's proving difficult to attach it to the correct ReactModalPortal div since they all appear to look the same.

diasbruno commented 3 years ago

@amille14 maybe you can use portalClassName...

diasbruno commented 3 years ago

You can try to get the node property of the modal, if you can make a reference to it....

amille14 commented 3 years ago

Ah ok, I think I can make portalClassName work for my purposes, thanks.

Victor-Jacon commented 2 years ago

@diasbruno

Your solution worked for me. Thanks a lot <3

giacomoalonzi commented 1 year ago

I didn't understand if this is the expected behavior or a bug. Thanks image

diasbruno commented 1 year ago

@giacomoalonzi This is the expected behavior.

Each modal you instantiate will create a node element where the modal will be placed when it opens up.

It's still open a feature request to allow react-modal to reuse the same node.

PRs are always welcome!

rutpshah commented 4 weeks ago

@diasbruno Is this still an open issue?