如何检测React Native应用程序何时打开?
我的React Native应用程序想要在用户打开应用程序时将其本地数据与API同步。这应该在用户返回应用程序时发生,而不仅仅是在第一次启动时。从本质上讲,我想要的是相当于AppDelegate的回调函数applicationDidBecomeActive
,这样我就可以在那里运行同步代码。很显然,我想在React Native中这样做。如何检测React Native应用程序何时打开?
据我所知,根组件上的componentWillMount
/componentDidMount
回调仅在最初加载应用程序时运行,而不是在用户离开应用程序并稍后返回(未明确退出应用程序)之后运行。
我认为AppState
API会提供此功能,但其change
侦听器在这种情况下也不会触发。
这似乎是明显的功能,所以我必须错过明显的东西。帮帮我!
我通过使用AppStateIOS
API而不是AppState
来解决此问题。后者在iOS设备上按预期工作:当应用程序转到后台时,将触发"change"
事件,并在该事件回到前台时再次发生。据我所知,在iOS设备上,AppState
API似乎并没有触发"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/>
}
})
当该组件被安装到一个阵营本机应用程序,你会看到关闭和打开应用程序时,“AppStateIOS改为...”。据我所知,您将从不请参阅“AppState更改为...”。
更新
看来,这是固定在阵营最近原住民(如V26的)。您现在可以使用在iOS和Android上宣传的AppState
。
我不认为你错过了什么。此功能仅仅是开箱即用的原生反应。也许这个想法是为了简化,因为对于大多数应用程序来说,当应用程序返回到前台时足以执行数据同步。
您可以创建自己的本机模块,它提供了这个功能,或者你可以用一个简单的(有点哈克的?)解决方案去:
在AppDelegate中保存的反应根视图的引用:
@interface AppDelegate()
@property (nonatomic, strong) RCTRootView *rootView;
@end
当初始化视图,设置你的财产,并使用它:
self.rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"MyApp"
initialProperties:nil
launchOptions:launchOptions];
现在实施处理像您激活状态W上的AppDelegate的方法在您的iOS应用乌尔德做和信息传递的道具:
-(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');
}
}
我不知道这是否是最好的办法,但它应该工作...
我认为你已经回答了你的问题。为什么不使用componentWillMount和AppState - >'change'的组合?这应该涵盖所有情况。我使用它通过CodePush同步我的应用程序。
我目前正在使用react-native 0.26.3和'AppState'按iOS和Android的预期工作,所以似乎不再需要'AppStateIOS'。 –
是的。看起来这是在最近版本的React Native中修复的。 – Mitch
我用过appstate。它适用于模拟器,但使用真实的ios设备时事件不会被解雇。 – Waqas