Reputation: 1638
I am using react-portal
to make a dialog and added transition, it went well as
// App.js
return (
<div className="App">
<button onClick={() => setIsOpen(true)}>Click to see dialog</button>
<PortalDialog isOpen={isOpen} setIsOpen={setIsOpen}>
This is content of dialog
</PortalDialog>
{/* animation works */}
</div>
)
//PortalDialog.js
return (
<Portal>
<DialogWrapper className={`${isOpen ? "active" : ""}`}>
{children}
<button onClick={() => setIsOpen(false)}>Close</button>
</DialogWrapper>
</Portal>
);
until I noticed PortalDialog
is created every time on render which I don't want so I added a condition
<div className="App">
<button onClick={() => setIsOpen(true)}>Click to see dialog</button>
{isOpen && (
<PortalDialog isOpen={isOpen} setIsOpen={setIsOpen}>
This is content of dialog
</PortalDialog> // animation doesn't work
)}
</div>
Now it's not rendered everytime but CSS transition doesn't work anymore and I think that's because of the condition I added. But I couldn't find a way to add transition with react-portal
, what do I need to do here ? I made a codesandbox example here.
Upvotes: 1
Views: 2268
Reputation: 1638
Looks like ReactTransitionGroup
is the answer, I wrapped my PortalDialog
component with CSSTransition
component as shown in their codesandbox sample.
<CSSTransition
in={isOpen}
timeout={300}
classNames="dialog"
unmountOnExit
>
<Portal>
<DialogWrapper>
{children}
<button onClick={() => setIsOpen(false)}>Close</button>
</DialogWrapper>
</Portal>
</CSSTransition>
Transition is now working without being created on every render.
Upvotes: 2