javascript - 在动画更新时从父组件更新子组件 DOM

标签 javascript reactjs

我已经设置了以下 Codepen 以供引用:
Animate React Ref GSAP
我有一个正在处理的 React 项目,例如,其中存在 2 个组件:一个 Pitch(如在足球场中)和一个 Player。 Pitch 是 Player 的父级,还有一个 forwardRef()用于从 Pitch 组件本身管理可能在球场上的每个球员的动画。
您还将在播放器组件 render() 中看到. SVG 包含一个 <g id="Position">...</g>应该随着动画的进行更新圆圈位置的分组。这就是我不知所措的地方。
在这个项目中,我使用 GSAP 来管理动画,但它实际上可以是任何动画库 - 如果我通过状态更改重新渲染 Player 组件来制作动画,甚至可能没有,但性能可能会令人担忧。 GSAP 提供了一个 onUpdate选择其 timeline.to()函数调用。可以从 ref 中读取 SVG 的位置值,但是尝试使用 ReactDOM.findDOMNode(component) 从父级更新其 DOM 是不好的做法。 [reference] .
因此,我的问题实际上归结为:

  • 如果直接从父级影响子元素的 DOM 不是最佳实践(我相信它甚至不可能从功能组件中实现,根据严格的 ESLint),那么我应该如何管理它?
  • 应该在 child 中触发动画吗?
  • 或者,我应该以某种方式从父级的状态重新渲染吗?


  • 如果我还没有说清楚,请告诉我,我会尽力澄清任何事情或一切!

    最佳答案

    在设计 React 组件时,您应该遵循几个关键原则。

  • 状态是事实的来源,所以你的组件如何显示(渲染)完全取决于状态(& prop)中数据的样子。永远不应该出现一种状态可以呈现为不同方式的情况。

  • 考虑到这一点,使用此代码 timeline.to(playerRef.current, { x: 0, y: 0, duration: 2 });并不是真正的“ react 方式”,因为它不会将玩家位置存储到状态中,而是使用另一件事(gsap)来操纵事物的显示方式(x,y 位置)
    这是更多的 react 方式
    // Pitch
    const Pitch = () => {
      const defaultPosition = { x: 210, y: 136 }
      const [playerPosition, setPlayerPosition] = useState(defaultPosition);
      
      const playMe = () => {
        setPlayerPosition({ x: 0, y: 0 });
      };
    
      const resetMe = () => {
        setPlayerPosition(defaultPosition);
      };
    
      return (
        <>
          <button type="button" onClick={playMe}>Play</button>
          <button type="button" onClick={resetMe}>Reset</button>
          <hr />
          <svg width="420px" height="272px" viewBox="0 0 420 272">
            <g id="Pitch">
              <rect id="Pitch-Background" fill="#409D41" x="0" y="0" width="420" height="272"></rect>
            </g>
            <Player position={playerPosition} />
          </svg>
        </>
      );
    
    }
    
    那么下一个问题将是“那么我们如何管理动画?”
    React Component 中 90% 的动画,您都希望在状态之间进行动画处理。状态 A 到状态 B 的转换。
    在 React 中管理动画方面,我可以分为 3 组。
  • 从预定义状态 A 到预定义状态 B 的转换
    (例如 div 打开 x = 200 到 div 关闭 x = 0)
  • 从状态 A 动态转换到状态 B(例如,移动到鼠标单击发生的位置)
  • 状态 A 到状态 B 之间的动画时间线/序列(例如,三个元素必须一个接一个地进行动画处理才能完成整个动画序列)

  • 如果您的用例属于 1. 然后 css transition是你的答案。
    如果您的用例属于 2. 然后 css transition可以是你的答案,也可以是一些动画库,例如 react-motion , react-spring , framer motion , 等等。
    如果您的用例属于 3。那么 GSAP 时间线就是您的大男孩。但是有一种特定的方式来写这个。在这一点上我不会详细介绍。

    同样,在您的示例中...假设它是 2。(从状态 A 动态转换到状态 B)。我们可以用 css transition 来解决这个问题.
    const Player = ({ position }) => {
      return (
        <g
          style={{ transition: `all 1s ease-out` }}
          transform={`translate(${newPosition.x},${newPosition.y})`}
        >
          <circle id="Oval" fill="#FF0000" cx="23" cy="39" r="19.5"></circle>
        </g>
    }
    
    这是我描述的工作代码。
    https://codepen.io/Doppy/pen/XWjNmdB
    附注。我在如何让玩家移动到鼠标点击位置的例子中也添加了:)
    祝你有美好的一天!

    关于javascript - 在动画更新时从父组件更新子组件 DOM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65185445/

    相关文章:

    javascript - Emberjs 1.0 : How to create Models and display them in another route?

    javascript - 在 D3.js 中设置 x 轴引用线

    javascript - 使用 nextjs 放大时,React Image Magnifiers 不起作用

    javascript - MouseEvent.path 在 Firefox 和 Safari 中等效

    javascript - 我可以在angular js asp.net mvc中调用Controller中的Route Provider服务吗

    javascript - 如何用 React Native 实现 Stripe?

    python - CentOS Apache服务器无法正确部署Dash 1.4.0,网页一直处于上传状态,为什么?

    javascript - 如何使用 webview 为 VSCode 扩展实现 React App 导航

    javascript - .change() 仅适用于当多个打开时的选择

    reactjs - 是否可以将material-ui按钮导航与react-router一起使用?