我有一个自定义模态,它在componentDidMount
:上滑动
componentDidMount() {
Animated.timing(this._animatedValue.y, {
duration: 200,
toValue: 0
}).start()
}
好吧,这很容易。然而,我也喜欢在组件卸载时将模态滑出。对我来说,componentWillUnmount()
感觉不错,因为它是一种优雅的声明方式:
componentWillUnmount() {
Animated.timing(this._animatedValue.y, {
duration: 200,
toValue: deviceHeight
}).start()
}
但这当然是不起作用的,因为React不会等到我完成动画。
所以目前我用一个自定义功能来解决这个问题:
closeModal() {
Animated.timing(this._animatedValue.y, {
duration: C.filterModalDuration,
toValue: deviceHeight
}).start()
InteractionManager.runAfterInteractions(() => {
this.props.UnmountThisComponent()
})
}
这当然没有那么优雅,但它很有效。然而,如果我需要从组件树中的一个组件调用这个函数,也就是说,我需要通过onUnmount={()=> closeModal()}
手动传递这个函数,然后用onUnmount={this.props.onUnmount}
一次又一次地传递。。。
然后我想我可以用redu&冗余连接。我想从子组件触发一个redux状态更改,然后通过componentWillRecieveProps()
调用函数,如下所示:
componentWillReceiveProps (nextProps) {
if (nextProps.closeFilter === true) {
this.closeModal()
}
}
然而,这让人感觉相当愤怒和迫切。
有什么方法可以以优雅/声明的方式解决这个问题吗
动画完成后,我不会使用InteractionManager.runAfterInteractions
执行。我建议使用start
回调。
Animated.timing(this.animatedValue, {}).start(() => this.props.closeModal())
比如https://github.com/mosesoak/react-native-conductor这可以帮助您协调深度动画并重新启动。这充分利用了context
。
你也可以像你尝试过的那样使用redux,但我会使用componentDidUpdate
而不是componentWillReceiveProps
。
原因是只有在componentWillReceiveProps
所在的组件中引发setState
才是安全的。
如果在componentWillReceiveProps
内部触发dispatch
,则会导致其他组件中的setState
导致应用程序中断。
总体而言:我推荐这种流程。(Close Action Initiated)=>动画模式关闭=>在start(() => {})
回调中导致setState
或在redux
存储中设置一段数据,然后unmount
将是现在隐藏的模式。
通过这种方式可以获得卸载动画。
如果您使用类似react-navigation
的路由,我建议您设置mode: "modal"
导航样式。这样,卸载/安装模式动画就可以为您处理了。
componentWillReceiveProps
似乎非常适合,因为它的意图是根据下一个道具进行操作。当父母想触发孩子的行为时,这是理想的选择(即使这不是React的模式,孩子调用父母函数,父母从孩子那里接收事件)。