【问题标题】:Framer Motion & React Portals : No Transitions OccurFramer Motion 和 React 门户:不发生过渡
【发布时间】:2021-11-29 21:55:44
【问题描述】:

我正在向现有网站添加一些 React 模块。为此,我正在通过 React 门户安装我的 React 组件。

简而言之,虽然我的组件确实按预期安装,但动画并未触发。例如,他们仍然坚持使用opacity0。我希望这些组件在挂载时从 opacity 0 过渡到 1,然后在退出时根据 initial animateexit 中每个孩子的道具从 0 过渡到 1 <AnimatePresence>.

可以在 CodeSandbox here 上找到显示该错误的人为但有效的示例。

CodeSandbox 中的代码如下所示:

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
   ...
  </head>

  <body>
    <div id="react-root"></div>
    <h1>Static Content</h1>
    <button id="start-portal">Show Modal</button>
    <div id="portal"></div>
  </body>
</html>

Context.js

import React from "react";

const INITIAL_STATE = {
  activeItem: -1
};

const Context = React.createContext(null);

const ContextProvider = ({ children }) => {
  const [store, setStore] = React.useState(INITIAL_STATE);

  React.useEffect(() => {
    const startEl = document.getElementById("start-portal");
    startEl.addEventListener("click", () => setActiveItem(0));
    return () => {
      startEl.removeEventListener("click", () => setActiveItem(0));
    };
  }, []);

  const setActiveItem = (activeItem) => {
    console.log("SETTING ACTIVE ITEM TO " + activeItem);
    setStore((prevState) => {
      return {
        ...prevState,
        activeItem
      };
    });
  };

  return (
    <Context.Provider
      value={{
        ...store,
        setActiveItem
      }}
    >
      {children}
    </Context.Provider>
  );
};

function useContext() {
  return React.useContext(Context);
}

export { ContextProvider, useContext };

index.js

import React from "react";
import ReactDOM from "react-dom";

import Modal from "./Modal";

import { ContextProvider } from "./Context";

import "./styles.css";

const REACT_ROOT = document.getElementById("react-root");
const PORTAL_ROOT = document.getElementById("portal");

const PortalModal = () => {
  if (!PORTAL_ROOT) return null;
  return ReactDOM.createPortal(<Modal />, PORTAL_ROOT);
};

const App = () => (
  <ContextProvider>
    <PortalModal />
  </ContextProvider>
);

ReactDOM.render(<App />, REACT_ROOT);

Modal.js

import React from "react";
import { AnimatePresence, m } from "framer-motion";

import { useContext } from "./Context";

const Modal = () => {
  const { activeItem, setActiveItem } = useContext();

  return (
    <AnimatePresence exitBeforeEnter>
      {activeItem === 0 && (
        <m.div
          key={"step-1"}
          className={"step"}
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
        >
          <h2>STEP 1</h2>
          <button onClick={() => setActiveItem(-1)}>CLOSE</button>
          <button onClick={() => setActiveItem(1)}>NEXT</button>
        </m.div>
      )}
      {activeItem === 1 && (
        <m.div
          key={"step-2"}
          className={"step"}
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
        >
          <h2>STEP 2</h2>
          <button onClick={() => setActiveItem(-1)}>CLOSE</button>
          <button onClick={() => setActiveItem(0)}>PREV</button>
        </m.div>
      )}
    </AnimatePresence>
  );
};

export default Modal;

【问题讨论】:

    标签: reactjs framer-motion react-portal


    【解决方案1】:

    您可以从m 切换到motion(在导入和组件中),一切正常。

    m 不是 motion 的 1:1 别名,而是精简版。 如果你想在m 组件中使用动画,你需要导入一个额外的“功能包”,比如domAnimationdomMax

    更多信息在这里: Framer.com: Reduce bundle size

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 2022-01-11
    • 2021-03-02
    • 2020-12-18
    • 2022-08-19
    • 2020-12-28
    • 2020-09-20
    相关资源
    最近更新 更多