react-native 都是怎么结束动画的

在开发中遇到以下这么一个问题:
主页面A push进了页面B
B页面中有网络请求,在请求数据的时候,自己写了一个无限循环的动画表示正在请求数据。动画的停止是靠state中的一个loading值来决定的。就比如下面的代码:

playAnimation() {

    Animated.timing(xxx, {
        toValue: xxx
    }).start(() => {
        this.state.loading && this.playAnimation;
    );
    
}

这样一来,当开始请求数据的时候,将loading的值改为true;数据请求结束的时候,再将loading的值设置为false。理想的情况下,动画没有问题,但是异常情况下问题就来了。。。

异常情况一:
(1) 当页面B正在加载数据时,用户点击了返回按钮使得页面B通过pop()退出回到页面A的时候,实验发现页面中的动画一直都存在,也就是loading还来不及置为false,导致动画一直结束不了。
(2) 想的解决方法是在componentWillUnmount的时候,通过this.setState()函数把loading的值改为false。但是试了之后发现,老是报warning,意思大致是在组件unmount时是不能修改state值的。所以又失败了。。。
(3)于是在constructor中加了this.stop的值来进一步控制。大意就是在componentWillUnmount的时候把this.stop的值改为true,然后在playAnimation的时候再判断当前的this.stop值是不是为true,true的话表示页面B即将销毁,所以动画不应该再继续。
(4)到这里,以为可以结束了,但是还没完。。。因为有异常情况二。。。

异常情况二:
(1)发现这个情况也是偶然,因为出现概率不是很高,但是还是可以重现的。场景就是当页面B刚进入的时候,用户就点击了返回按钮使得页面B又退出返回到主页面A,这个时候发现动画还是结束不了
(2)这里有一点很奇怪的是,通过实验发现,明明componentWillUnmount函数已经执行了,但是componentDidMount还是执行了,所以猜测这两步操作很可能应该是异步执行的?
(3)正是因为这个原因,所以在页面B已经退出返回到主页面A的时候,隔了两三秒之后时常会报warning警告,即在组件unmount时是不能修改state值的。猜测这很可能是因为组件已经unmount了之后,在componentDidMount中去setState loading的值了。所以一直报warning,而且动画也还是停不下来。

造成的结果很严重。。。
由于为了保证页面B进入动画的流畅性,我是在componrntDidMount里面用了InteractionManager.runAfterInteractions方法的,也就是说只有在页面中无交互了才会干相应的事情(请求数据 + 等待数据加载的动画)。但是由于上一次进入页面B又异常退出页面B而导致停不下来的动画,runAfterInteractions会一直等待这个动画结束,从而造成了请求数据的阻塞。。。崩盘。。。

求教大家一般都是怎么处理这个问题的。。。。

阅读 6.8k
1 个回答

这算是一个竞态问题了。有个思路你可以试试,就是在componentWillMount的时候先把this.willmount设置为true,然后在componentDidMount里面检查this.willmount是否为true再执行loading动画逻辑,在componenWillUnmount里面将this.willmount设置为false。这样如果componentWillUnmount在componentDidMount之前执行了,那么componentDidMount应该就不会执行loading显示了。

还有一个方案是引入rxjs,比如 redux-observable,rxjs解决竞态问题还是比较好用的。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题