Может возникнуть ситуация, когда вам нужно сохранить (сохранить) ваше состояние редукции из хранилища редуктов в локальное хранилище вашего браузера, в ситуациях перезагрузки страницы, выхода из системы, закрытия вкладки, закрытия браузера и т. д.

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

Это взято из курса 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 не чаще одного раза в секунду.

Постоянное (сохраненное) состояние теперь будет доступно для использования вашим компонентом.