【问题标题】:Router state not being persisted in react-native with redux路由器状态没有通过 redux 保持在 react-native
【发布时间】:2017-01-24 10:28:24
【问题描述】:

我在react-native 中有以下redux 配置,使用react-native-router-flux 和redux-persist。我想在刷新时检索最后一个当前路由,但是路由堆栈在重新加载时被覆盖。

这是reducers/index.js 文件

import { combineReducers, createStore, applyMiddleware, compose } from 'redux'
import { persistStore, autoRehydrate } from 'redux-persist'
import { AsyncStorage } from 'react-native'
import logger from 'redux-logger'

import { startServices } from '../services'
import navigation from './navigation'
import devices from './devices'
import rooms from './rooms'


import { ActionConst } from 'react-native-router-flux'

function routes (state = {scene: {}}, action = {}) {
  switch (action.type) {
    // focus action is dispatched when a new screen comes into focus
    case ActionConst.FOCUS:
      return {
        ...state,
        scene: action.scene,
      };

    // ...other actions

    default:
      return state;
  }
}

export const reducers = combineReducers({
  routes,
  navigation,
  devices,
  rooms
})

const middleware = [logger()]

const store = createStore(
  reducers,
  compose(
    autoRehydrate(),
    applyMiddleware(...middleware)
  )
)

persistStore(store, {storage: AsyncStorage}, function onStoreRehydrate () {
  startServices()
})

export { store, reducers }

编辑:这是index.js 及其提供者和场景:

import React, { Component } from 'react'
import { store } from './reducers'
import { Provider, connect } from 'react-redux'
import { Router, Scene, Actions } from 'react-native-router-flux';

import Home from './containers/home'
import Login from './containers/login'
import Device from './containers/device'


const scenes = Actions.create(
  <Scene key="root">
      <Scene key="home" component={Home} />
      <Scene key="login" component={Login} />
      <Scene key="device" component={Device} />
  </Scene>
)

const RouterWithRedux = connect()(Router)

export default class EntryPoint extends Component {
  render () {
    return (
      <Provider store={store}>
        <RouterWithRedux scenes={scenes} />
      </Provider>
    )
  }
}

【问题讨论】:

    标签: reactjs react-native redux react-redux react-native-router-flux


    【解决方案1】:

    react-native-router-flux 不会自行恢复场景,即使与 redux 一起使用也是如此。 Redux 只跟踪状态,因此如果您希望导航状态保持不变,您必须让应用在启动时导航到上一个场景。

    假设您有使用 react-native-router-flux 的 redux,您只需将应用的初始组件连接到 redux 以获取您的状态,然后更改您的场景以匹配。

    因此,在为您的应用加载的初始组件场景中,最后执行以下操作以访问您的 redux 存储:

    const mapStateToProps = (state) => {
      const { nav } = state
    
      return {
        currentScene: nav.scene.name,
      }
    }
    
    INITIAL_COMPONENT = connect(mapStateToProps)(INITIAL_COMPONENT)
    

    然后在该组件的生命周期方法之一中,您可以像这样重定向:

    const { currentScene } = this.props
    const initialScene = "Login"
    
    if (currentScene !== initialScene) {
      Actions[currentScene]()
    }
    

    您还可以传入导航到最后一个场景时使用的道具,或者如果 redux 商店没有持续存在的场景,则可以设置您想要去的默认场景。我正在开发的应用程序现在可以很好地保持状态。

    【讨论】:

    • 必须在初始场景的ComponentWillUpdate中完成,这将导致初始场景在过渡到最后访问的场景之前显示。有什么办法可以避免吗?
    • 我还没有找到避免这种情况的方法,但是到目前为止,我在大多数情况下都运行过它,它不会持续很长时间。在此期间,我会继续寻找替代方案。
    【解决方案2】:

    你需要像这样创建你的store:

    const store = createStore(
      reducers,
      compose(
        applyMiddleware(...middleware),
        autoRehydrate(),
      )
    );
    

    autoRehydrate 必须是您的compose 的一部分。检查this compose example。

    【讨论】:

    • 其实我也试过了。 autoRehydrate 可以表现得和增强器一样好。
    • 你有一个我可以玩的回购吗?
    • 对不起,我没有公开的回购分享
    【解决方案3】:

    你能试试这个吗?我认为发生的是 createStore 的顺序

    const enhancers = compose(
      applyMiddleware(...middleware),
      autoRehydrate(),
    );
    
    // Create the store with the (reducer, initialState, compose)
    const store = createStore(
      reducers,
      {},
      enhancers
    );
    

    或者其他解决方案应该使用 import {REHYDRATE} from 'redux-persist/constants' 手动执行并在您的减速器中调用它。

    【讨论】:

      猜你喜欢
      • 2018-05-02
      • 2017-02-02
      • 2017-04-27
      • 1970-01-01
      • 2018-10-03
      • 1970-01-01
      • 2016-04-06
      • 1970-01-01
      • 2021-03-08
      相关资源
      最近更新 更多