React Native Navigation и Redux Persist

Я пытаюсь интегрировать redux-persist с wix react-native-navigation. Однако я не могу найти какие-либо примеры или документацию с указанием стандартного кода, необходимого для интеграции обеих библиотек.

Мне было интересно, если кто-нибудь хотел бы поделиться своим решением, если они решили эту проблему?


person Kamil Kamili    schedule 09.12.2017    source источник
comment
Удачи с этим? Я застрял на той же проблеме.   -  person RedOster    schedule 18.12.2017
comment
Нет, я перешел на React Navigation, но я оставил это открытым для любых ответов.   -  person Kamil Kamili    schedule 24.12.2017


Ответы (4)


Прежде всего, базовая настройка должна быть такой же, с реактивной навигацией или без нее, как описано в документации в store.js:

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 принимает обратный вызов в качестве третьего аргумента. Обратный вызов выполняется после восстановления/регидратации состояния. Это хорошо, потому что это означает, что мы можем отложить запуск экранов до тех пор, пока состояние не восстановится.

Предположим, у вас есть следующий загрузочный код в App.js:

store = configureStore()

registerScreens(store, Provider)

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

Теперь мы можем добавить persistStore и обернуть в него ваш загрузочный код следующим образом:

store = configureStore()

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

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

Примечание. В версии 4 вы передаете config вместо null: persistStore(store, config, callback)

person Leo Lei    schedule 01.01.2018

Если вы хотите интегрировать его с react-native-navigation v2, в App.js убедитесь, что вы вызываете persistStore() внутри registerAppLaunchedListener() :

import { persistStore } from 'redux-persist';
...
Navigation.events().registerAppLaunchedListener(() => {
  persistStore(store, null, () => {
    Navigation.registerComponentWithRedux(...);
    ...
    Navigation.setRoot({...})
     ...
  })
})
person Jojo    schedule 16.01.2019
comment
Где взять провайдера? - person Omar S.; 10.05.2019

Добавляя к его решению, вы также можете использовать 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")
})
person Stephen Tapia    schedule 20.06.2018

На самом деле нам не нужен redux-persist. Мы можем сделать наш собственный redux-persist с помощью:

redux + store.subscribe(handlechange)

Функция handleChange будет запускаться, когда что-то изменится в нашем магазине.

Также с помощью aync-await(promise) мы не блокируем основной поток выполнения.

Итак, внутри создайте магазин, добавьте что-то вроде:

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

Затем внутри App.js (первый компонент для загрузки). используйте AsyncStorage.getItem('store'). Затем обновите магазин перед запуском приложения.

localstorage в Интернете — это синхронная функция, которая блокирует основной поток.

AsynsStorage в react-native не блокирует основной поток.

person Rajender Dandyal    schedule 03.03.2019