2016-02-01 135 views
17

我的React Native應用程序想要在用戶打開應用程序時將其本地數據與API同步。這應該在用戶返回應用程序時發生,而不僅僅是在第一次啓動時。從本質上講,我想要的是相當於AppDelegate的回調函數applicationDidBecomeActive,這樣我就可以在那裏運行同步代碼。很顯然,我想在React Native中這樣做。如何檢測React Native應用程序何時打開?

據我所知,根組件上的componentWillMount/componentDidMount回調僅在最初加載應用程序時運行,而不是在用戶離開應用程序並稍後返回(未明確退出應用程序)之後運行。

我認爲AppState API會提供此功能,但其change偵聽器在這種情況下也不會觸發。

這似乎是明顯的功能,所以我必須錯過明顯的東西。幫幫我!

+2

我目前正在使用react-native 0.26.3和'AppState'按iOS和Android的預期工作,所以似乎不再需要'AppStateIOS'。 –

+2

是的。看起來這是在最近版本的React Native中修復的。 – Mitch

+0

我用過appstate。它適用於模擬器,但使用真實的ios設備時事件不會被解僱。 – Waqas

回答

16

我通過使用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

0

我不認爲你錯過了什麼。此功能僅僅是開箱即用的原生反應。也許這個想法是爲了簡化,因爲對於大多數應用程序來說,當應用程序返回到前臺時足以執行數據同步。

您可以創建自己的本機模塊,它提供了這個功能,或者你可以用一個簡單的(有點哈克的?)解決方案去:

在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'); 
    } 
} 

我不知道這是否是最好的辦法,但它應該工作...

0

我認爲你已經回答了你的問題。爲什麼不使用componentWillMount和AppState - >'change'的組合?這應該涵蓋所有情況。我使用它通過CodePush同步我的應用程序。

+0

不幸的是,據我所知,AppState - >'change''在用戶打開或關閉應用程序時根本不會觸發。所以我只能檢測到應用程序首次啓動時。 – Mitch

+1

嗯。根據我的經驗它確實如此。我有AppStateIOS.addEventListener('更改',this.onAppStateChange);在我的根組件的componentDidMount方法中。每當我回到主屏幕或回來時它都會閃光。 –

+0

好的。感謝您的跟蹤!我會再試一次並報告。 – Mitch

相關問題