[英]How to make a react custom component animated using react-spring
我有一个名为HomeContent
的反应自定义组件,它接受一些道具。
根据我制作的 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" />
但我看到道具没有通过。 请告诉我该怎么做。
这取决于你想如何与你的组件交互,你想使用 api 还是仅仅提供更新的道具?
// update by regenerating springProps from some other state
const springProps = useSpring(props)
// update springProps with api
const [springProps, api] = useSpring(() => props)
在第一个示例中,使用其中一个动画原生元素( animated.XXX
),您将在每次想要更新 state 时重新渲染动画包装,因为每次更新它时都会传递一个新的、更新的springProps
object,它将导致它重新渲染。 当您使用在包装器内不使用 ref 而不是本机元素之一的自定义元素时,该组件将为每个 animation 帧重新渲染一次。 从性能的角度来看,这是次优的,但使用此策略,您可以使用您想要的组件的任何 api(道具名称),就像您所做的那样。
这是一个使用此解决方案的沙箱:沙箱
您可以观察到 animation 可以正常工作,但组件会重新渲染很多。
如果您想提高效率,并使用 api 更新您的自定义组件,您需要遵守一些规则。 当您使用 api 时, react-spring
通过相应 DOM 元素上的 ref 更新元素,因此, react-spring
必须了解如何更新元素而不需要 React 重新渲染它。 这意味着:
forwardRef
不允许您添加多个 ref,所以如果您想将其包装在animated
中,则无法在自定义组件内的多个 DOM 元素上进行更改(还有其他策略可以解决此问题,例如不将组件包装在animated
中和而是在您的组件中使用本机animated.XXX
元素并将SpringValue
作为道具传递)。react-spring
将无法理解如何更新这个元素。 由于您的元素有很多自定义属性, react-spring
将无法通过 api 更新您的组件。 它将尝试通过简单地在 ref 附加到的元素上设置更新的属性来做到这一点,但是由于您需要对 map 做出反应,将自定义属性设置为 DOM 元素上的实际属性,这将失败(我没有知道有您提供的一组属性)。
作为如何完成此操作的示例,以下是一个显示此策略大纲的沙箱:沙箱
在这里你可以看到组件只渲染一次并且仍然可以更新。 您还可以看到,包裹在animated
中的自定义组件上使用的属性对应于div
元素上的 props,从而使react-spring
能够完全按照我们的意愿行事( AnimatedHomeContent
的子项是 React 中名为props.children
的特殊 props react-spring
知道如何处理)。
<AnimatedHomeContent style={{ backgroundColor: spring.backgroundColor }}>
{spring.content}
</AnimatedHomeContent>
在沙箱中也是一个使用其他属性名称的坏例子。
<AnimatedHomeContentBad
backgroundColor={spring.backgroundColor}
content={spring.content}
/>
为了从这个版本中获得正确的行为,React 必须将组件处理为 map 输入道具到本机 DOM 元素道具。 当通过 api 更新此版本时, react-spring
不会重新渲染组件(因为它可以接受 ref),而是在 ref 附加到的元素上设置更新的属性(检查控制台中的元素以亲自查看这些道具是在更新后设置的)。 由于属性不是真正的属性,因此组件上没有任何更新或动画。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.