React Native Navigation 和 Redux Persist

React Native Navigation and Redux Persist

我正在尝试将 redux-persist 与 wix react-native-navigation 集成。但是,我找不到任何示例或文档来说明集成这两个库所需的样板代码。

我想知道如果有人解决了这个问题,是否愿意分享他们的解决方案?

首先,基本设置应该与 store.jsin the documentation 中描述的带或不带 react-native-navigation 的设置类似:

import { persistStore, persistCombineReducers } from 'redux-persist'
import storage from 'redux-persist/es/storage' // default: 
localStorage if web, AsyncStorage if react-native
import reducers from './reducers' // where reducers is an object of 
reducers

const config = {
  key: 'root',
  storage,
}

const reducer = persistCombineReducers(config, reducers)

function configureStore () {
  // ...
  let store = createStore(reducer)
  return store

  // We'll skip persistStore for now
  // let persistor = persistStore(store)
  //return { persistor, store }
}

persistStore 调用被注释掉,因为我们将在下面进行。 persistStore 方法在其第三个参数中接受回调。状态为restored/rehydrated后执行回调。这很好,因为这意味着 我们可以延迟启动屏幕,直到状态重新水化

假设您在 App.js 中有以下 bootstrap 代码:

store = configureStore()

registerScreens(store, Provider)

Navigation.startTabBasedApp({
  tabs: [{...},]
})

现在我们可以添加 persistStore 并将您的 bootstrap 代码包装在其中,如下所示:

store = configureStore()

persistStore(store, null, () => {
  registerScreens(store, Provider)

  Navigation.startTabBasedApp({
    tabs: [{...},]
  })
})

注意: 在 v4 中,您传递 config 而不是 nullpersistStore(store, config, callback)

添加到他的解决方案中,您还可以使用 subscribe() 检查您的用户是否仍在登录。这样,如果他们完全关闭应用程序,他们就不需要再次登录(对于那些登录的用户系统),并且因为它只在商店持久化后被调用,所以您可以在选中后启动您的应用程序。

    import {Platform, AsyncStorage, AppState} from "react-native"
    import {Navigation} from "react-native-navigation"
    import {registerScreens} from "./routes"
    import {Provider} from "react-redux"
    import configureStore from "./stores/reduxStore"
    import {Component} from "react"

      const storage = configureStore()

      registerScreens(Provider, storage.store)

let startapp = screen => {
  Navigation.startSingleScreenApp({
    screen: {
      screen, // unique ID registered with Navigation.registerScreen
      navigatorStyle: {
        navBarHidden: true,
        statusBarHidden: false,
        statusBarColor: "white",
        statusBarTextColorScheme: "dark"
      }, // override the navigator style for the screen, see "Styling the navigator" below (optional)
      navigatorButtons: {} // override the nav buttons for the screen, see "Adding buttons to the navigator" below (optional)
    },
    drawer: {
      left: {
        screen: "Drawer", // unique ID registered with Navigation.registerScreen
        passProps: {} // simple serializable object that will pass as props to all top screens (optional)
      }
    },
    tabsStyle: {
      // optional, add this if you want to style the tab bar beyond the defaults
      tabBarButtonColor: "#ffff00", // optional, change the color of the tab icons and text (also unselected). On Android, add this to appStyle
      tabBarSelectedButtonColor: "#ff9900", // optional, change the color of the selected tab icon and text (only selected). On Android, add this to appStyle
      tabBarBackgroundColor: "#551A8B", // optional, change the background color of the tab bar
      initialTabIndex: 1 // optional, the default selected bottom tab. Default: 0. On Android, add this to appStyle
    },
    appStyle: {
      orientation: "portrait"
    }
  })
}

storage.persistor.subscribe(() => {
  storage.store.getState().user.logged
    ? startapp("mainscreen")
    : startapp("loginscreen")
})

如果您希望将它与 react-native-navigation v2 集成,在 App.js 中,确保您在 registerAppLaunchedListener() 中调用 persistStore() :

import { persistStore } from 'redux-persist';
...
Navigation.events().registerAppLaunchedListener(() => {
  persistStore(store, null, () => {
    Navigation.registerComponentWithRedux(...);
    ...
    Navigation.setRoot({...})
     ...
  })
})

我们实际上不需要 redux-persist。我们可以让我们自己的 redux-persist 使用:

redux + store.subscribe(handlechange)

handleChange 功能将 运行 当我们商店发生变化时。

同样使用 aync-await(promise) 我们不会阻塞主执行线程。

所以在 create store 中添加如下内容:

store.subscribe(async ()=>{
 try {
 await AsyncStorage.setItem("store", JSON.stringify(store.getState()));
 } catch (error) {
  // Error 
 } 
})

然后在 App.js(要加载的第一个组件)中。使用 AsyncStorage.getItem('store')。然后在应用启动前更新商店。

网上的

localstorage是一个阻塞主线程的同步函数。

AsynsStorage 在 react-native 中不会阻塞主线程。