Я хочу сохранить некоторые части моего дерева состояний в localStorage. Какое подходящее место для этого? Редуктор или действие?
источник
Я хочу сохранить некоторые части моего дерева состояний в localStorage. Какое подходящее место для этого? Редуктор или действие?
Редуктор никогда не подходит для этого, потому что редукторы должны быть чистыми и не иметь побочных эффектов.
Я бы порекомендовал просто сделать это в подписчике:
store.subscribe(() => {
// persist your state
})
Перед созданием магазина прочитайте эти сохраненные части:
const persistedState = // ...
const store = createStore(reducer, persistedState)
Если вы используете, combineReducers()
вы заметите, что редукторы, которые не получили состояние, будут «загружаться» как обычно, используя значение state
аргумента по умолчанию . Это может быть очень удобно.
Желательно, чтобы вы отменили подписку, чтобы не писать слишком быстро в localStorage, иначе у вас будут проблемы с производительностью.
Наконец, вы можете создать промежуточное программное обеспечение, которое инкапсулирует это как альтернативу, но я бы начал с подписчика, потому что это более простое решение и хорошо выполняет свою работу.
Чтобы заполнить пробелы в ответе Дана Абрамова, вы можете использовать
store.subscribe()
так:Перед созданием магазина проверьте
localStorage
и проанализируйте любой JSON под вашим ключом, например так:Затем вы передаете эту
persistedState
константу в вашcreateStore
метод следующим образом:источник
persistedState
возвращатьсяinitialState
вместо пустого объекта? В противном случае я думаю, чтоcreateStore
будет инициализироваться с этим пустым объектом.Одним словом: промежуточное ПО.
Проверьте избыточно-постоянный . Или написать свой.
[ОБНОВЛЕНИЕ 18 декабря 2016 года] Отредактировано, чтобы удалить упоминание о двух похожих проектах, которые сейчас неактивны или устарели.
источник
Если у кого-то есть проблемы с вышеуказанными решениями, вы можете написать свое собственное. Позвольте мне показать вам, что я сделал. Игнорировать
saga middleware
вещи, просто сосредоточиться на двух вещахlocalStorageMiddleware
иreHydrateStore
методе.localStorageMiddleware
тянуть всеredux state
и помещает его вlocal storage
иrehydrateStore
тянут всеapplicationState
в локальном хранилище , если присутствует , и помещает его вredux store
источник
localStorage
даже если ничего в магазине не изменилось? Как вы компенсируете ненужные записиЯ не могу ответить @Gardezi, но вариант на основе его кода может быть:
разница в том, что мы просто сохраняем некоторые действия, вы можете использовать функцию debounce для сохранения только последнего взаимодействия вашего состояния
источник
Я немного опоздал, но я реализовал постоянное состояние в соответствии с примерами, приведенными здесь. Если вы хотите обновлять состояние только каждые X секунд, этот подход может помочь вам:
Определить функцию обертки
Вызовите функцию обертки в вашем подписчике
В этом примере состояние обновляется максимум каждые 5 секунд, независимо от того, как часто запускается обновление.
источник
(state) => { updateLocalStorage(store.getState()) }
вlodash.throttle
так:store.subscribe(throttle(() => {(state) => { updateLocalStorage(store.getState())} }
и удалить время проверки логики внутри.Опираясь на отличные предложения и выдержки из коротких кодов, приведенные в других ответах (и средней статье Джема Кричии ), вот полное решение!
Нам нужен файл, содержащий 2 функции, которые сохраняют / загружают состояние в / из локального хранилища:
Эти функции импортируются из store.js, где мы настраиваем наш магазин:
ПРИМЕЧАНИЕ. Вам нужно добавить одну зависимость:
npm install lodash.throttle
Хранилище импортируется в index.js, поэтому его можно передать провайдеру, который упаковывает App.js :
Обратите внимание, что для абсолютного импорта требуется это изменение в YourProjectFolder / jsconfig.json - это говорит ему, где искать файлы, если он не может их найти сначала. В противном случае вы увидите жалобы на попытки импортировать что-то извне src .
источник