17

У меня есть следующая конфигурация redux в react-native с использованием 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 } 

EDIT: Это index.js с его Provider и сцены:

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> 
    ) 
    } 
} 

ответ

0

react-native-router-flux не восстанавливает сцену сам по себе, даже если используется с сокращением. Redux только отслеживает состояние, поэтому вам нужно, чтобы ваше приложение переходило к предыдущей сцене при запуске, если вы хотите, чтобы ваше состояние навигации сохранялось.

Предполагая, что у вас есть сокращение, работающее с react-native-router-flux, все, что вам нужно сделать, это подключить исходный компонент приложения к сокращению, чтобы получить свое состояние, а затем сменить сцену на соответствие.

Таким образом, в вашей начальном компоненте сцене загруженной для вашего приложения, сделать что-то вроде этого в конце, чтобы получить доступ к вашему 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]() 
} 

вы также могли бы пройти в реквизите, которые были использованы при переходе к последней сцене или сцены по умолчанию вы хотите перейти, если перевождь магазин не имеет сцены, это сохраняющееся. Приложение, над которым я работаю, сейчас прекрасно сохраняется.

+0

Это должно быть сделано в ComponentWillUpdate начальной сцены, что приведет к отображению начальной сцены, прежде чем она будет перенесена на последнюю доступную сцену. Есть ли способ избежать этого? – Avery235

+0

Я еще не нашел способа избежать этого, но в большинстве сценариев я его запустил до сих пор, это не очень долго. Тем временем я буду искать альтернативы. –

0

Вам нужно создать свой store так:

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

autoRehydrate должен быть частью вашего compose. Проверьте this compose example.

+0

Я действительно пробовал это также. 'autoRehydrate' может вести себя как энхансер. – jsdario

+0

Есть ли у вас репо, с которым я могу поиграть? – rclai

+0

Извините, у меня нет публичного репо для обмена – jsdario

0

Вы можете попробовать это, я думаю, что это произойдет порядок 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' и вызвать его внутри редуктора.

Смежные вопросы