Может возникнуть ситуация, когда вам нужно сохранить (сохранить) ваше состояние редукции из хранилища редуктов в локальное хранилище вашего браузера, в ситуациях перезагрузки страницы, выхода из системы, закрытия вкладки, закрытия браузера и т. д.
Пример, в котором вы хотите, чтобы браузер помнил, посещал ли пользователь ваш сайт в прошлом, и вы хотите использовать эту информацию для отображения формы уведомления для них.
Это взято из курса Redux egghead.io Дэна Абрамова.
Во-первых, мы создадим новый файл с функциями загрузки и сохранения состояния.
1. Реализовать функцию, загружающую состояние из localStorage
// localStorage.js export const loadState = () => { try { const serializedState = localStorage.getItem('state'); if (serializedState === null) { return undefined; } return JSON.parse(serializedState); } catch (err) { return undefined; } };
loadState
просматривает localStorage браузера. Если есть сериализованная строка состояния, она будет анализировать ее как JSON.
Важно, чтобы этот фрагмент кода был заключен в блок try
/catch
, потому что вызовы localStorage.getItem
могут завершиться ошибкой, если режим конфиденциальности пользователя не позволяет использовать localStorage.
Если что-то пойдет не так, мы вернем undefined
, чтобы приложение не вылетало.
2. Реализовать функцию, сохраняющую состояние в localStorage.
// localStorage.js export const saveState = (state) => { try { const serializedState = JSON.stringify(state); localStorage.setItem('state', serializedState); } catch { // ignore write errors } };
В этой функции состояние сериализуется в строку с помощью JSON.stringify
. Это будет работать, только если состояние сериализуемо. Наличие сериализуемого состояния является общей рекомендацией в Redux.
Затем мы будем использовать возвращаемое значение loadState в качестве второго аргумента для создания хранилища, чтобы оно переопределяло начальное состояние, указанное редьюсерами.
3. Подпишитесь на магазин
// store.js import {throttle} from 'lodash'; const persistedState = loadState(); const store = createStore( app, persistedState ); store.subscribe(throttle(() => { saveState({ todos: store.getState().todos }); }, 1000));
Функция saveState
вызывается внутри прослушивателя store.subscribe
, поэтому она вызывается каждый раз при изменении состояния хранилища. Однако его не следует вызывать слишком часто, поскольку он использует дорогостоящую операцию JSON.stringify
.
Чтобы решить эту проблему, мы будем использовать библиотеку lodash
, которая включает в себя удобную утилиту throttle
. Заключение обратного вызова в throttle
гарантирует, что передаваемая внутренняя функция не будет вызываться чаще, чем указано в миллисекундах. Теперь, даже если это хранилище вызывается очень быстро, у нас есть гарантия, что мы будем писать в localStorage не чаще одного раза в секунду.
Постоянное (сохраненное) состояние теперь будет доступно для использования вашим компонентом.