Open winkcor opened 1 month ago
in below code element render but exit animation not working
return( createPortal( <AnimatePresence> {isOpen && <>...</>} </AnimatePresence>, document.body ) );
Hi @winkcor, I've tried out this solution, it seems fine to me. CodeSandbox
https://github.com/framer/motion/assets/35992041/ff4c1b0a-ba3d-46ef-8277-3b1b81099527
Environments:
Chrome 125.0.6422.114 (Official Build) (arm64)
macOS Sonoma 14.5
in below code element render but exit animation not working
return( createPortal( <AnimatePresence> {isOpen && <>...</>} </AnimatePresence>, document.body ) );
Hi @june21x, you are right, this code works, but this is a server component, if we do not set the isOpen condition before createPortal
, the component will be rendered on the server side, and the document.body
is not defined on the server, and if you look at the server console, you will see the following error:
⨯ src\components\modal\index.tsx (51:15) @ document
⨯ ReferenceError: document is not defined
at ModalContainer.Modal (./src/components/modal/index.tsx:81:23)
digest: "3267920918"
49 | }
50 | </AnimatePresence>
>51 | , document.body, this.key);
| ^
52 |
53 | };
54 | }
to fix that we can add if (typeof window === "undefined") return;
before createPortal
.
but I think if we could use the following code its so much better, but with this code, the component is not rendered
<AnimatePresence> {isOpen && createPortal( <>...</>, document.body )} </AnimatePresence>
@winkcor I see, I have modified my solution to align with your requirement, by wrapping a Fragment
around createPortal()
. CodeSandbox
<AnimatePresence>
{isOpen &&
<>
{createPortal(
<>...</>,
document.body
)}
</>
}
</AnimatePresence>
Based on the source code here,
My guess is that <AnimatePresence/>
doesn't detect ReactPortal
as its children because somehow ReactPortal
is not a valid ReactElement
(even though ReactPortal
does extends ReactElement
) when validated with isValidElement()
. That's why it's not rendering.
console.log(isValidElement(createPortal(<></>, document.body)})); // false
console.log(isValidElement(<>{createPortal(<></>, document.body)}</>)); // true
1. Read the FAQs 👇
2. Describe the bug
AnimatePresence only work when it send as children to createPortal it not effected when its as parent of createPortal.
3. IMPORTANT: Provide a CodeSandbox reproduction of the bug
A CodeSandbox
4. Steps to reproduce this is not work and element not render
in below code element render but exit animation not working
5. Expected behavior
AnimatePresence and Exit animation work for createPrtal as regular JSX element.
7. Environment details