Kaung Khant Zaw
Kaung Khant Zaw

Reputation: 1638

CSS transition doesn't work with react-portal

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

Answers (1)

Kaung Khant Zaw
Kaung Khant Zaw

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

Related Questions