大家在RN中都是怎么结束动画的。。。



  • 在开发中遇到以下这么一个问题:
    主页面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会一直等待这个动画结束,从而造成了请求数据的阻塞。。。崩盘。。。

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



  • 正常pop是动画会结束的,没办法重现你的动画。
    你就this.animation = Animated(...)
    执行动画就用this.animation.start();
    然后componentWillUnmount() {this.animation.stop()}



  • 动画不复杂用gif就好了,无限循环动画效果,时间长了会造成内存溢出奔溃,如果有runAfterInteractions存在很可能造成卡顿或不执行等现象


登录后回复