React-native:将动画值保持在状态或作为类属性?

Posted

技术标签:

【中文标题】React-native:将动画值保持在状态或作为类属性?【英文标题】:React-native: Keep animated values in state or as class property? 【发布时间】:2017-03-19 02:27:41 【问题描述】:

将动画值 (fadeAnim) 保留为状态属性更好还是将其设置为类属性?

例子:

class ModalShade extends React.Component 
    fadeAnim = new Animated.Value(0)

    render() 
        return (
            <Animated.View
                cls="bg-black absolute-fill"
                style= opacity: this.fadeAnim 
            />
        )
    

    componentDidMount() 
        Animated.spring(
            this.fadeAnim, 
                toValue: 0.6,
                tension: 100,
                friction: 20
            
        ).start();
    

说明: 我知道状态用于反应的和解。 React-native'Animated 值绕过通常的 render(),因此即使没有状态更改,组件也会更新。

在我的shouldComponentUpdate 中比较Animated.Value 没有任何意义,这就是我将其移出状态的原因。

【问题讨论】:

您终于找到了存储动画值的最佳做法吗?我遇到了您的问题,因为我遇到了同样的困境,官方文档中的示例使用状态来存储 Animated 值,但这似乎适得其反。 我使用实例变量。 是的,这对我来说很奇怪。 react-native 中的大多数官方示例都将 Animated.Value 存储在状态中。对我来说,如果我们在组件属性中存储Animated.Value,我认为它们中的大多数应该没问题。 我开始意识到官方的 react-native 文档、支持和代码质量都不是很好。 【参考方案1】:

最好遵循官方文档并使用国家财产。 有两个很好的理由:

    您希望将所有对组件渲染结果有影响的内容保留在您的 state/props/context 中。 React-Native 动画库有自己的优化,可以避免 setState 调用和重新渲染动画组件的变化。这是官方文档的引用

当组件挂载时,不透明度设置为 0。然后,在 fadeAnim 动画值上启动缓动动画,这将更新其在每一帧上的所有相关映射(在本例中,只是不透明度)作为value 动画到最终值 1。

这是以比调用 setState 和重新渲染更快的优化方式完成的。

【讨论】:

但我在每个组件的shouldUpdate 内部都做了 deepEquals,这也会遍历这些对象。【参考方案2】:

一般来说,使用 React 将某些内容存储为实例/类属性(例如 this.myVar = 'foo';)或存储在状态中存在很大差异。不同之处在于 React 使用状态对象来确定何时重新渲染组件(即再次调用 render() )。

如果您将变量存储为类/实例属性然后更改它,React 渲染逻辑不知道该更改的任何内容,因此您不会在渲染的 UI 中看到任何更改。

所以你应该在 state 中存储改变组件渲染输出的东西。如果一个变量根本不影响渲染的输出(并且您根本不在乎在它发生变化时收到通知),那么您可以将其存储为实例/类属性。有时这会对性能产生更好的影响,因为更新该变量的 setState 调用会触发不必要的渲染。

在您的示例中,您省略了渲染方法,但很可能您需要访问状态中的 fadeAnim 变量才能实际执行动画。基本上,Animated.spring 只是随着时间的推移插入一些值,但是你需要使用这些插入的值来实际动画一些东西。 在文档示例 (https://facebook.github.io/react-native/docs/animated.html) 中,您可以看到 this.state.fadeAnimrender 中用于控制(动画)不透明度样式。

回顾一下,您需要将fadeAnim 存储在状态中,因为值的更改会触发重新渲染。

【讨论】:

感谢您的回复。我没有省略 render 方法,它在上面的示例中。此外,虽然您的回答总体上是正确的,但它不适用于 Animated/react-native。动画不是通过render() 运行,而是通过使用Animated.spring 来启动动画。这种机制绕过了 React 的协调和虚拟 dom,因此我的问题。 我明白了,感谢您的评论。出于好奇,我检查了源代码,正如你所说,动画确实是由本机代码处理的:github.com/facebook/react-native/blob/master/Libraries/Animated/… 我认为像你那样将它移出状态看起来是个好主意,恐怕我不这样做'但是没有真正的证据可以提供。

以上是关于React-native:将动画值保持在状态或作为类属性?的主要内容,如果未能解决你的问题,请参考以下文章

css3动画如何在动作结束时保持该状态不变

路由器状态没有通过 redux 保持在 react-native

如果输入是垃圾邮件,Unity动画属性将保持禁用状态

在 react-native 中隐藏和显示带有动画的 createBottomTabNavigator 选项卡栏

当 graphql 变量的状态发生变化时,react-native 上的结果保持不变

无法更新状态 - react-native