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.fadeAnim
在 render
中用于控制(动画)不透明度样式。
回顾一下,您需要将fadeAnim
存储在状态中,因为值的更改会触发重新渲染。
【讨论】:
感谢您的回复。我没有省略 render 方法,它在上面的示例中。此外,虽然您的回答总体上是正确的,但它不适用于 Animated/react-native。动画不是通过render()
运行,而是通过使用Animated.spring
来启动动画。这种机制绕过了 React 的协调和虚拟 dom,因此我的问题。
我明白了,感谢您的评论。出于好奇,我检查了源代码,正如你所说,动画确实是由本机代码处理的:github.com/facebook/react-native/blob/master/Libraries/Animated/… 我认为像你那样将它移出状态看起来是个好主意,恐怕我不这样做'但是没有真正的证据可以提供。以上是关于React-native:将动画值保持在状态或作为类属性?的主要内容,如果未能解决你的问题,请参考以下文章
路由器状态没有通过 redux 保持在 react-native
在 react-native 中隐藏和显示带有动画的 createBottomTabNavigator 选项卡栏