我有一个自定义模式,可以在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}
。 ..
然后我认为我可以用redux&终极版-CONNECT。我想从子组件触发redux状态更改,然后通过componentWillRecieveProps()
调用该函数,如下所示:
componentWillReceiveProps (nextProps) {
if (nextProps.closeFilter === true) {
this.closeModal()
}
}
然而,这感觉非常hacky和必要。
有没有办法以优雅/陈述的方式解决这个问题?
答案 0 :(得分:7)
动画完成后我不会使用InteractionManager.runAfterInteractions
来执行。我建议使用start
回调。
Animated.timing(this.animatedValue, {}).start(() => this.props.closeModal())
像https://github.com/mosesoak/react-native-conductor这样的东西可以帮助你协调深层动画并重新启动。这利用了context
。
您也可以尝试使用redux,但我会使用componentDidUpdate
而不是componentWillReceiveProps
。
原因是,只有在您拥有setState
的组件中componentWillReceiveProps
才会安全。
如果您在dispatch
内触发componentWillReceiveProps
,则会导致其他组件中的setState
导致您的应用程序中断。
start(() => {})
回调中导致setState
或在redux
商店中设置一段数据,然后unmount
您的模式现在被隐藏。
这样你就可以获得卸载动画。
如果您使用react-navigation
之类的路由,建议您设置mode: "modal"
导航样式。这样就可以为你解决卸载/安装模态动画。
答案 1 :(得分:2)
componentWillReceiveProps
似乎非常合适,因为它的目的是根据下一个道具制作动作。当父母想要对他们的孩子采取行动时,这是理想的选择(即使这并不是React的模式,孩子们称父母为其功能,父母也会从孩子那里接受事件)。