首页 文章

如何检测何时打开React Native应用程序?

提问于
浏览
21

我的React Native应用程序希望在用户打开应用程序时将其本地数据与API同步 . 这应该在用户返回应用程序时发生,而不仅仅是在第一次启动时 . 基本上,我想要的是相当于AppDelegate的 applicationDidBecomeActive 回调,以便我可以在那里运行同步代码 . 显然,我想在React Native中这样做 .

据我所知,根组件上的 componentWillMount / componentDidMount 回调仅在最初加载应用程序时运行,而不是在用户离开应用程序并稍后返回(未明确退出应用程序)之后运行 .

我认为 AppState API会提供此功能,但它的 change 侦听器也不会在这种情况下触发 .

这似乎是明显的功能,所以我必须错过一些明显的东西 . 救命!

3 回答

  • 19

    我不认为你错过了什么 . 开箱即用的react-native不提供此功能 . 也许这个想法是为了简化,因为对于大多数应用程序来说,当应用程序返回到前台时,它足以执行数据同步 .

    您可以创建自己的本机模块来提供此功能,也可以使用简单的(一种hacky?)解决方案:

    在您的AppDelegate中保存对react根视图的引用:

    @interface AppDelegate()
    @property (nonatomic, strong) RCTRootView *rootView;
    @end
    

    初始化视图时,设置属性并使用它:

    self.rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                moduleName:@"MyApp"
                                         initialProperties:nil
                                             launchOptions:launchOptions];
    

    现在实现AppDelegate方法来处理活动状态,就像在iOS应用程序中那样,并将信息作为props传递:

    -(void)onAppActiveStateChanged:(BOOL)appBecameActive
    {
      NSMutableDictionary *newProps = [NSMutableDictionary dictionary];
      if (self.rootView.appProperties != nil) {
        [newProps addEntriesFromDictionary:self.rootView.appProperties];
      }
      newProps[@"appDidBecomeActive"] = @(appBecameActive);
      self.rootView.appProperties = newProps;
    }
    
    - (void)applicationWillResignActive:(UIApplication *)application
    {
      [self onAppActiveStateChanged:NO];
    }
    
    - (void)applicationDidBecomeActive:(UIApplication *)application
    {
      [self onAppActiveStateChanged:YES];
    }
    

    在JavaScript方面,在道具改变时做你需要的任何事情:

    componentWillReceiveProps(nextProps) {
      if (nextProps.appDidBecomeActive) {
        alert('app did become active');
      }
    }
    

    我不确定这是否是最好的方法,但它应该有效......

  • 1

    我通过使用 AppStateIOS API而不是 AppState 来修复此问题 . 后者在iOS设备上按预期工作:当应用程序进入后台时, "change" 事件将触发,并且当它返回到前台时再次触发 . 据我所知, AppState API在iOS设备上根本不会触发 "change" 事件,就像React Native v0.18一样 . 该项目的约定表明 AppState 应该是 AppStateIOS 的跨平台包装器,但这似乎并非如此 .

    以下示例应演示此问题:

    React.createClass({
    
      componentDidMount() {
        AppStateIOS.addEventListener('change', state =>
          console.log('AppStateIOS changed to', state)
        )
    
        AppState.addEventListener('change', state =>
          console.log('AppState changed to', state)
        )
      },
    
      render() {
        return <View/>
      }
    
    })
    

    将此组件安装到React Native应用程序中时,您将在关闭并打开应用程序时看到"AppStateIOS changed to ..." . 据我所知,你永远不会看到"AppState changed to ..." .

    Update

    似乎最近在React Native中修复了这个问题(截至第26条) . 您现在可以在iOS和Android上使用 AppState 广告 .

  • 0

    我想你已经回答了你自己的问题 . 为什么不使用componentWillMount和AppState的组合 - >'更改'?这应该涵盖所有情况 . 我使用它来通过CodePush同步我的应用程序 .

相关问题