5 ответов:
редуктор никогда не является подходящим местом для этого, потому что редукторы должны быть чистыми и не иметь побочных эффектов.
Я бы рекомендовал просто сделать это в подписчике:
store.subscribe(() => { // persist your state })
перед созданием магазина прочитайте эти сохраненные части:
const persistedState = // ... const store = createStore(reducer, persistedState)
если вы используете
combineReducers()
вы заметите, что редукторы, которые не получили состояние, будут "загружаться" как обычно, используя их по умолчаниюstate
значение аргумента. Это может быть очень удобно.это рекомендуется отказаться от подписки, Чтобы не писать в localStorage слишком быстро, или у вас будут проблемы с производительностью.
наконец, вы можете создать промежуточное программное обеспечение, которое инкапсулирует это в качестве альтернативы, но я бы начал с подписчика, потому что это более простое решение и хорошо выполняет эту работу.
чтобы заполнить пробелы в ответе Дана Абрамова, вы можете использовать
store.subscribe()
такой:store.subscribe(()=>{ localStorage.setItem('reduxState', JSON.stringify(store.getState())) })
перед созданием магазина, чек
localStorage
и разбирать любой JSON под вашим ключом, как это:const persistedState = localStorage.getItem('reduxState') ? JSON.parse(localStorage.getItem('reduxState')) : {}
вы тогда передайте это
peristedState
константа для вашегоcreateStore
способ такой:const store = createStore( reducer, persistedState, /* any middleware... */ )
одним словом: middleware.
проверить redux-persist. Или написать свой собственный.
[UPDATE 18 Dec 2016] отредактировано, чтобы удалить упоминание о двух подобных проектах, которые теперь неактивны или устарели.
если у кого-то есть какие-либо проблемы с вышеуказанными решениями, вы можете написать свой собственный. Позвольте мне показать вам, что я сделал. Игнорировать
saga middleware
все просто сосредоточиться на двух вещахlocalStorageMiddleware
иreHydrateStore
метод. элементlocalStorageMiddleware
вытащить всеredux state
и кладет его вlocal storage
иrehydrateStore
вытащить всеapplicationState
в локальном хранилище, если присутствует и ставит его вredux store
import {createStore, applyMiddleware} from 'redux' import createSagaMiddleware from 'redux-saga'; import decoristReducers from '../reducers/decorist_reducer' import sagas from '../sagas/sagas'; const sagaMiddleware = createSagaMiddleware(); /** * Add all the state in local storage * @param getState * @returns {function(*): function(*=)} */ const localStorageMiddleware = ({getState}) => { // <--- FOCUS HERE return (next) => (action) => { const result = next(action); localStorage.setItem('applicationState', JSON.stringify( getState() )); return result; }; }; const reHydrateStore = () => { // <-- FOCUS HERE if (localStorage.getItem('applicationState') !== null) { return JSON.parse(localStorage.getItem('applicationState')) // re-hydrate the store } } const store = createStore( decoristReducers, reHydrateStore(),// <-- FOCUS HERE applyMiddleware( sagaMiddleware, localStorageMiddleware,// <-- FOCUS HERE ) ) sagaMiddleware.run(sagas); export default store;
Я не могу ответить @Гардези, но на основе его кода может быть:
const rootReducer = combineReducers({ users: authReducer, }); const localStorageMiddleware = ({ getState }) => { return next => action => { const result = next(action); if ([ ACTIONS.LOGIN ].includes(result.type)) { localStorage.setItem(appConstants.APP_STATE, JSON.stringify(getState())) } return result; }; }; const reHydrateStore = () => { const data = localStorage.getItem(appConstants.APP_STATE); if (data) { return JSON.parse(data); } return undefined; }; return createStore( rootReducer, reHydrateStore(), applyMiddleware( thunk, localStorageMiddleware ) );
разница в том, что мы просто сохраняем некоторые действия, вы можете использовать функцию debounce, чтобы сохранить только последнее взаимодействие вашего состояния
Comments