【问题标题】:How to make a react custom component animated using react-spring如何使用 react-spring 制作一个 react 自定义组件动画
【发布时间】:2021-03-13 11:55:30
【问题描述】:

我有一个名为 HomeContent 的 react 自定义组件,它接受一些道具。

按照我制作的 react-spring 文档制作动画

const animatedHomeContent = animated(HomeContent);

然后为了渲染,我这样做了:

 <animatedHomeContent
    id={1}
    avatar="O"
    image="..."
    image_title="Onion"
    title=" Medium Sized Onions"
    subtitle="November 08, 2020"
    desc="Onions from farms of Nasik"
    price="74"
    quantity="1kg"
/>

但我看到道具没有通过。 请告诉我该怎么做。

【问题讨论】:

    标签: javascript reactjs react-spring


    【解决方案1】:

    这取决于你想如何与你的组件交互,你想使用 api 还是仅仅提供更新的 props?

    // update by regenerating springProps from some other state
    const springProps = useSpring(props) 
    
    // update springProps with api
    const [springProps, api] = useSpring(() => props) 
    

    通过再生弹簧进行更新

    在第一个示例中,使用其中一个动画原生元素 (animated.XXX),您将在每次想要更新状态时重新渲染动画包装,因为您每次都会传递一个新的、更新的 springProps 对象您更新它,这将导致它重新呈现。或者...这只是部分正确,返回对象中的单个 SpringValue 将与两种方法相同,因此如果您将它们作为单独的道具传递,理论上不需要重新渲染,但如果您将它们作为整个对象(例如,当 springPropsstyle 对象时)它将是上次渲染后更改的对象,并导致 animated 包装器的重新渲染。

    当您使用在包装器内不使用 ref 的自定义元素而不是原生元素之一时,组件将为每个动画帧重新渲染一次。从性能的角度来看,这是次优的,但是通过这种策略,您可以为组件使用您想要的任何 api(prop 名称),就像您所做的那样。

    这是一个使用此解决方案的沙盒:sandbox

    您可以观察到动画可以正常工作,但也可以看到组件重新渲染了很多。

    通过 api 更新

    如果您想提高效率,并使用 api 更新您的自定义组件,您需要遵守一些规则。当您使用 api 时,react-spring 通过相应 DOM 元素上的 ref 更新元素,因此,react-spring 必须了解如何更新元素而不需要 React 重新渲染它。这意味着:

    • 您的自定义元素必须能够保存引用
    • 您的自定义元素必须将 ref 附加到您希望在其上发生所有动画的 DOM 元素。因为forwardRef 不允许您添加多个引用,所以如果您想将自定义组件内的多个 DOM 元素包装在 animated 中,则无法对它进行更改(还有其他策略可以解决此问题,例如不包装您的animated 中的组件,而是使用组件内的原生 animated.XXX 元素并将 SpringValues 作为道具传递)。
    • 您的自定义组件的属性名称必须与您要更新的 ref 附加到的 DOM 元素上的属性相对应。否则react-spring 将无法理解如何更新此元素。

    由于您的元素有很多自定义属性,react-spring 将无法通过 api 更新您的组件。它将尝试通过简单地在 ref 附加到的元素上设置更新的属性来做到这一点,但是由于您需要 React 将自定义属性映射到 DOM 元素上的实际属性,这将失败(我没有知道有你提供的一组属性)。

    作为如何完成此操作的示例,这里有一个显示此策略大纲的沙盒:sandbox

    在这里你可以看到组件只渲染了一次并且仍然可以更新。您还可以看到,包裹在animated 中的自定义组件上使用的属性对应于div 元素上的props,从而使react-spring 能够完全按照我们的意愿行事(AnimatedHomeContent 的子元素是React 命名为 props.childrenreact-spring 知道如何处理)。

    <AnimatedHomeContent style={{ backgroundColor: spring.backgroundColor }}>
        {spring.content}
    </AnimatedHomeContent>
    

    在沙盒中也是一个使用其他属性名称的坏例子。

    <AnimatedHomeContentBad
        backgroundColor={spring.backgroundColor}
        content={spring.content}
    />
    

    为了从这个版本中获得正确的行为,React 必须处理组件以将输入道具映射到本机 DOM 元素道具。通过 api 更新此版本时,react-spring 不会重新渲染组件(因为它可以获取 ref),而是在 ref 所附加的元素上设置更新的属性(检查控制台中的元素以亲自查看这些道具是在更新后设置的)。由于属性不是真正的属性,因此组件上没有任何更新或动画。

    【讨论】:

      猜你喜欢
      • 2020-10-07
      • 1970-01-01
      • 2020-07-28
      • 1970-01-01
      • 1970-01-01
      • 2020-01-27
      • 2017-09-08
      • 1970-01-01
      • 2016-09-30
      相关资源
      最近更新 更多