redux persist что это
Redux-Persist: How it Works and How to Change the Structure of Your Persisted Store
3min à lire ⬝ 13 février 2019
Redux persist is a library allowing to save the redux store in the local storage of your browser.
But, using redux-persist and changing the store’s architecture could trigger issues. This article illustrates, with a basic example, how persistence works with your Redux store, then focus on the persisted store’s transformation across code versions and app uses.
To install it in your project, I recommend you read the documentation or this article.
How to persist a store and how it works
Let’s take, as an example, this redux store from a React project, generated with create-react-app:
I implemented redux-persist as explained in the official doc and my store. You can find all the code in this repo.
There is a custom function persist(), to define in persistConfig only what’s changed for this article.
Steps of persistence:
Persistence with Redux-persist occurs in 3 mains steps. To show it, i use Redux devTools chrome extension : INIT, PERSIST and REHYDRATE.
While visiting the app, the redux store is created as the initial state given through the reducers. This defines the first content of your app, and persistence has not done its job yet.
During persist step, in every persisted store, an object is added with this configuration:
The rehydrated value is a boolean used to check if the persistence has been applied yet, it will be used later.
This phase is where the persisted data stored in browser replace the data in Redux store.
Across all reducers, every local state is «rehydrated» and is replaced by the persisted store.
Each reducer replaces their content by the persisted one.
That allows us to keep information during sessions of navigation (or if you refresh your page).
You now have your redux store with value in your storage.
Modifying the architecture of the Redux Store
Developing a new feature impacting the store architecture or refactoring a part of your store could trigger an inconsistency between the persisted store with the old architecture and new pushed architecture.
Indeed, the initial state represents the new version of your code, but during rehydration, every persisted store will be replaced by the same key-named persisted store, keeping the old architecture.
For example illustrated by the image below, if I want to change the architecture of my store to add the last update information to my number of change, steps of persistence are:
@INIT: initial state set the form I need
persist/PERSIST: _persist object is added with rehydrated false
persist/REHYDRATE: persisted data replace the Redux store.
What went wrong here?
The variable ‘number’, which is supposed to have the structure of the new version of the app, is replaced by the old persisted structure. You lose all your store changes.
This inconsistency can jeopardize the use of your code if you don’t anticipate them.
Handling it with a version-controlled store.
Redux-persist allows you to transform your store depending on the version you want for the app: you can control the version of your store.
To do this, use the function createMigrate() and pass in the persistConfig object in migrate» key:
Migrations are applied on your state before replacing your store data in REHYDRATE step.
For example, with this definition of the passed migrations, your state will be reset as the initial state and you will have the expected behaviour during REHYDRATE:
You can use createMigrate() function to transform persisted data architecture to fit with your new store: For our previous example, keeping the data will be:
This version 1 of migration will put my previous number of change where I want.
To note changes and debug your migrations, you can set the debug version to true to log which migrations are applied.
To go further and see how migrations are applied, you can look at the source code of createMigrate() function.
Step Back
In some cases, you may not use migrations.
There is more pragmatic solutions that could solve this problem faster:
Conclusion
To my mind, version controlled redux store should be used when:
How To Use Redux Persist In React Application
Feb 16, 2019 · 3 min read
In this article, I will explain my understanding of Redux persistence.
How does Redux Persistence work?
Redux persist takes your Redux state object and save it to Persistence storage.
For example, If we store your redux reducers using redux persist, It will not clear when you close your app. You have that old data when you open your app again.
Whenever you uninstall your app, at that time only your reducers will be clear.
How do we use Redux Persist?
For pre-request, we should have to configure with redux. Follow this guideline for install redux.
Installation for redux persist:
For pe r sistReducer is wrap your app’s root reducers and pass it to the persistStore function it ensures your redux state is stored to persisted storage whenever it changes.
In persistConfig I used the whitelist. It (whitelist) ensures which reducer want to save in persistence storage rest of the reducers are not save in persistence storage.
In the above code authType is one of the reducers. But authType data only store in the storage.
The above one is my authType reducer. This reducer data save in persistence storage.
blacklist is also one of the keys in persistConfig. It defines which are the reducers do not want to save in the persistence storage.
In your provider you just your store alone.
This basic my understanding of redux persistence knowledge. Want to more follow below links….
Запросы GraphQL без подключения к сети с помощью Redux Offline и Apollo
Забавно, но с распространением интернета в мире все больше востребованы веб-приложения, работающие без подключения к сети. Пользователи (и клиенты) хотят функциональные интернет-приложения в онлайн, офлайн и в зонах с неустойчивой связью.
Посмотрим, как создать эффективное решение, работающее без подключения к сети, на React и слое данных GraphQL с применением Apollo Client. Статья разбита на две части. На этой неделе разберем оффлайновые запросы. На следующей неделе примемся за мутации.
Redux Persist и Redux Offline
За спиной Apollo Client все тот же Redux. А это значит, вся экосистема Redux с многочисленными инструментами и библиотеками доступна в приложениях на Apollo.
В сфере поддержки офлайн у Redux два основных игрока: Redux Persist и Redux Offline.
Redux Persist прекрасный, но дающий лишь основу, инструмент для загрузки хранилища redux в localStorage и восстановления обратно (поддерживаются и другие места хранения). По принятой терминологии, восстановление также называется регидрацией.
Redux Offline расширяет возможности Redux Persist дополнительным слоем функций и утилит. Redux Offline автоматически узнает о разрывах и восстановлениях связи и при разрыве позволяет ставить в очередь действия и операции, а при восстановлении – автоматически воспроизводит эти действия вновь.
Redux Offline – это «заряженый» вариант для работы без сетевого подключения.
Запросы в офлайн
Apollo Client и сам неплохо справляется с краткосрочными перебоями сетевых подключений. Когда сделан запрос, его результат помещается в собственное хранилище Apollo.
Если тот же запрос делается повторно, результат немедленно берется из хранилища на клиенте и отдается запрашивающему компоненту, кроме случая, когда параметр fetchPolicy имеет значение network-only. Это значит, что при отсутствии сетевого подключения или недоступности сервера повторные запросы будут возвращать последний сохраненный результат.
Однако стоит пользователю закрыть приложение, и хранилище пропадет. Как не потерять хранилище Apollo на клиенте между перезапусками приложения?
На помощь приходит Redux Offline.
Apollo держит свои данные в хранилище Redux (в ключе apollo ). Записывая хранилище целиком в localStorage и восстанавливая при следующем запуске приложения, можно переносить результаты прошлых запросов между сеансами работы с приложением даже при отсутствии подключения к интернету.
Использование Redux Offline и Apollo Client не обходится без нюансов. Посмотрим, как заставить работать вместе обе библиотеки.
Создание хранилища вручную
Обычно клиент Apollo создается довольно просто:
Конструктор ApolloClient автоматически создает хранилище Apollo (и косвенно – хранилище Redux). Полученный экземпляр client подается в компонент ApolloProvider :
При использовании Redux Offline необходимо вручную создавать хранилище Redux. Это позволяет подключить к хранилищу промежуточный обработчик (middleware) из Redux Offline. Для начала просто повторим то, что делает сам Apollo:
Теперь можно подать store в компонент ApolloProvider :
Превосходно. Создание хранилища Redux под контролем, и можно продолжать с Redux Offline.
Основы персистентного хранения запросов
В простейшем случае добавление Redux Offline заключается в добавлении еще одного промежуточного обработчика к хранилищу.
Откройте консоль и получите из localStorage эту запись:
Выводится большой объект JSON, представляющий полное текущее состояние приложения Apollo.
На все запросы, результаты которых находятся в этом хранилище, будут возвращены данные даже при отсутствии подключения к серверу.
Конкуренция при восстановлении хранилища
Увы, восстановление хранилища происходит не мгновенно. Если приложение делает запрос в то время, как Redux Offline восстанавливает хранилище, могут происходить Странные Вещи(tm).
Если в Redux Offline включить логирование для режима autoRehydrate (что само по себе заставляет понервничать), при первоначальной загрузке приложения можно увидеть ошибки, на подобии:
Посмотрим на другое решение.
Подключим созданный редьюсер к хранилищу и настроим Redux Offline так, чтобы по окончанию восстановления выполнялось новое действие.
Добавление rehydrate в массив blacklist гарантирует, что эта часть хранилища не будет записана в localStorage и восстановлена из него.
Теперь, когда в хранилище есть сведения об окончании восстановления, разработаем компонент, реагирующий на изменения поля rehydrate и визуализирующий дочерние компоненты, только если rehydrate равно true :
Странности и пояснения
Есть несколько странностей и требующих пояснения вещей при использовании Redux Offline вместе с клиентом Apollo.
Другая странность этой пары в том, что Redux Offline, кажется, не слишком хорошо уживается с Apollo Client Devtools. Попытки использовать Redux Offline с установленным Devtools иногда приводят к неожиданным и, казалось бы, бессвязным ошибкам.
Такие ошибки можно легко исключить, если при создании Apollo client не подключать его к Devtools.
Будьте на связи
Redux Offline дает приложению на Apollo основые механизмы для выполнения запросов даже при перезагрузке приложения после отключения от сервера.
Через неделю погрузимся в обработку офлайновых мутаций с помощью Redux Offline.
Перевод статьи. Автор оригинала Pete Corey.
Redux persist что это
Redux Toolkit Persist
Persist and rehydrate a redux store. This is a fork of redux-persist that implements @reduxjs/toolkit (replacing the core redux dependency) as well as upgrading various dependencies to more recent versions.
npm install reduxjs-toolkit-persist
Basic usage involves adding persistReducer and persistStore to your setup. IMPORTANT Every app needs to decide how many levels of state they want to «merge». The default is 1 level. Please read through the state reconciler docs for more information.
If you are using react, wrap your root component with PersistGate. This delays the rendering of your app’s UI until your persisted state has been retrieved and saved to redux. NOTE the PersistGate loading prop can be null, or any react instance, e.g. loading=
Redux Toolkit Usage
Redux Toolkit gives us more options. This example will use createSlice and configureStore.
Note: persistCombineReducers defaults to the autoMergeLevel2 State Reconciler.
persistStore(store, [config, callback])
State reconcilers define how incoming state is merged in with initial state. It is critical to choose the right state reconciler for your state. There are three options that ship out of the box, let’s look at how each operates:
Redux persist ships with react integration as a convenience. The PersistGate component is the recommended way to delay rendering until persistence is complete. It works in one of two modes:
Nested persist can be useful for including different storage adapters, code splitting, or deep filtering. For example while blacklist and whitelist only work one level deep, but we can use a nested persist to blacklist a deeper value:
persistReducer has a general purpose «migrate» config which will be called after getting stored state but before actually reconciling with the reducer. It can be any function which takes state as an argument and returns a promise to return a new state object.
Transforms allow you to customize the state object that gets persisted and rehydrated.
There are several libraries that tackle some of the common implementations for transforms.
Below is a Transform that successfully persists a Set property, which simply converts it to an array and back. In this way, the Set gets converted to an Array, which is a recognized data structure in JSON. When pulled out of the persisted store, the array gets converted back to a Set before being saved to the redux store.
The createTransform function takes three parameters.
In order to take effect transforms need to be added to a PersistReducer ’s config object.
5 Методов сохранения состояния в промежутках между перезагрузками страниц в React
1. LocalStorage — классовые компоненты
Один из простых вариантов для сохранения состояния — использовать localStorage в браузере. Рассмотрим пример:
Это простой подход для сохранения состояния в классовых компонентах. Посмотрим, как добиться того же в функциональном компоненте.
2. LocalStorage — функциональные компоненты
Первым делом преобразуем компонент, основанный на классах, в функциональный компонент:
A теперь посмотрим, как при добавлении localStorage в функциональный компонент с состоянием добиться сохранения этого состояния:
3. LocalStorage с Redux Store
Но при сохранении состояния в localStorage на уровне компонента возникает одна проблема. И связана она с наличием нескольких экземпляров одного и того же компонента. Это приводит к неожиданному поведению, так как в localStorage создаются повторяющиеся ключи.
У этой проблемы два решения:
Для сохранения состояния приложения в localStorage будем использовать Redux.
4. Redux Persist
Вместо того, чтобы заниматься сохранением и восстановлением состояния вручную, используем библиотеку, которая поможет нам с этой задачей справиться.
А сохранять и инициализировать persistStore нам помогает persistReducer из Redux Persist.
5. Параметры URL
Наконец добрались до самого очевидного варианта — использования параметров URL для сохранения состояния. А этот подход годится, в случае если данные предельно простые и со значениями-примитивами. Это обусловлено ограничениями по длине URL.
Если приглядеться к этому коду, то мы заметим, что он добавляет состояние в историю браузера. Поэтому при инициализации компонента мы наследуем исходные значения параметров URL.
Одно из существенных преимуществ здесь — это возможность сохранения состояний для перезагрузки, а также перемещения между историческими состояниями с помощью кнопки браузера «Назад».
Заключение
Чтобы упростить себе задачу и не заниматься сохранением и восстановлением состояния приложения вручную, задействуем библиотеки типа Redux Persist.
Какой бы вариант вы не выбрали, важно также сохранять контроль над изменениями состояния. Ведь после того, как состояние будет установлено, у некоторых пользователей приложение не сможет продолжать работу, если в более новой версии вы измените код, связанный с этим состоянием.