如何使用 Framer Motion <AnimatePresence> 和 React Portal?

vis*_*Inc 7 javascript animation reactjs framer-motion

情况

我使用React Portals构建了一个 React Modal组件(请参阅上面的文档)。在单击关闭按钮时卸载组件之前,我想使用AnimatePresence通过 Framer Motion 运行动画。不幸的是,我无法让它发挥作用,需要帮助。exit

链接

我尝试过的

我添加exit={{ opacity: 0 }}了一个孩子<RenderModal/>。输入动画使用initial并按animate预期工作。

  1. 环绕<AnimatePresence>模态根元素
<div id="root"></div>
<AnimatePresence>
  <div id="modal-root"></div>
</AnimatePresence>
Run Code Online (Sandbox Code Playgroud)
  1. 包装为 modal-root 的子级

错误:目标容器需要 DOM 元素

<div id="modal-root">
  <AnimatePresence></AnimatePresence>
</div>
Run Code Online (Sandbox Code Playgroud)
  1. 环绕组件元素
const Modal = ({
    title,
    footer,
    children,
  }) => {
   <AnimatePresence>
    {isVisible
      && (
        <RenderModal
          title={title}
          footer={footer}
          hide={hide}
        >
          {children}
        </RenderModal>
      )}
    </AnimatePresence>
  };
Run Code Online (Sandbox Code Playgroud)
  1. 包裹使用过的组件
return (
  <>
    <Button onClick={show}>Open Modal</Button>
    <AnimatePresence>
      <Modal {...args}></Modal>
    </AnimatePresence>
    <p>Lorem ipsum dolor sit amet...</p>
  </>
);
Run Code Online (Sandbox Code Playgroud)

小智 8

你好,我想可能会迟到。但我用这段代码解决了


import { ReactNode } from "react";
import ReactDOM from "react-dom";
import { AnimatePresence } from "framer-motion";

interface ModalWrapperProps {
    children: ReactNode;
    isShowing: boolean;
}

const ModalWrapper = ({ children, isShowing }: ModalWrapperProps) =>
    ReactDOM.createPortal(
        <AnimatePresence exitBeforeEnter>
            {isShowing && children}
        </AnimatePresence>,
        document.body
    );

export default ModalWrapper;

Run Code Online (Sandbox Code Playgroud)

我在下面的帖子中受到启发

https://blog.logrocket.com/implementing-animated-toasts-in-react/


Cad*_*din 0

key您是否记得为条件渲染元素添加一个道具?我在你的代码片段中没有看到它。

来自文档

每个子运动组件必须有一个唯一的 key prop,以便 AnimatePresence 可以跟踪它们在树中的存在。