
Содержание статьи
Память всегда являлась неотъемлемой частью создания программ. Создавая веб-приложение для нашей компании, мне нужен был надежный, простой в использовании способ сохранения моих состояний в хранилище, который можно настроить в соответствии с требованиями.
К счастью, эта библиотека была ответом на все мои проблемы!
Эта статья основана на проблеме, с которой я столкнулся при работе над проектом. Давайте погрузимся глубже и поймем, как библиотека помогла мне решить это.
Если вы еще не использовали redux-persist, то прочтите документацию, поскольку она не требует пояснений. Если вы хотите знать, почему вам следует использовать эту библиотеку, просмотрите эту статью – это замечательное интро от самого автора!
проблема
Давайте возьмем пример, где я хотел сохранить редуктор в своем localStorage:
//Reducer
reducerA: {
engine: {
model: "F5AAA",
manufacturer: "Ferrari"
},
tyre: {
model: "T123",
manufacturer: "MRF",
owner: {
details: {
name: "Zack",
age: "26"
}
}
},
condition: "prime"
}
//View
class TestComponent extends React.Component {
render() {
const model = someStateOfReducerA.tyre.model
const manufacturer = someStateOfReducerA.tyre.manufacturer
return (
<div>{model}</div>
<div>{manufacturer}</div>
)
}
}
//Reducer in localStorage
reducerA: {
engine: {
model: "F5AAA",
manufacturer: "Ferrari"
},
tyre: {
model: "T123",
manufacturer: "MRF",
owner: {
details: {
name: "Zack",
age: "26"
}
}
},
condition: "prime"
}
Теперь этот редуктор сохранился в устройстве нашего клиента. Итак, что произойдет, если я введу новый ключ для нашего редукторA?
reducerA: {
engine: {
model: "F5AAA",
manufacturer: "Ferrari"
},
tyre: {
model: "T123",
manufacturer: "MRF",
owner: {
details: {
name: "Zack",
age: "26",
address: "CA" // NEW KEY ADDED
}
}
},
condition: "prime"
}
Скажем, у нас есть представление, отражающее значение нашего недавно представленного ключа:
//View with new key address
class TestComponent extends React.Component {
render() {
const model = someStateOfReducerA.tyre.model
const manufacturer = someStateOfReducerA.tyre.manufacturer
const address = someStateOfReducerA.tyre.owner.details.address
return (
<div>{model}</div>
<div>{manufacturer}</div>
<div>{address}</div>
)
}
}
Когда я загружаю свою программу с помощью недавно введенного ключа, рендеринг нашего просмотра не удается. Он выдает ошибку, где говорится:
Cannot render address of undefined
Это произошло из-за того, что память клиента синхронизирована с rootReducer, инициализированным при перезагрузке программы.
Несмотря на то, что мы представили новый ключ, хранилище клиента так и не получило его. Он инициализирует наш rootReducer старыми значениями в хранилище, где адрес никогда не существовал, и влечет за собой воспроизведение нашего компонента.
Решение
Это приводит к хорошо известной концепции: миграция базы данных.
Схема миграция выполняется на a базы данных всякий раз, когда это необходимо обновить или вернуть базы данных схемы к новой или более старой версии. Миграции выполняются программно с помощью схемы миграция инструмент — Википедия
LocalStorage действительно является небольшой базой данных пар ключ-значения. Redux Persist делает это здорово. Если вы посмотрите на проект, инициализированный этой библиотекой, он уже использует a версия по умолчанию -1. Воспользуйтесь снимком экрана, сделанным из вкладки приложения в инструменте разработчика Chrome.

Это действительно хорошо! Библиотека уже поддерживает для нас по умолчанию версию, чтобы мы могли включить функцию миграции в будущем.
Главное – настроить постоянную конфигурацию в rootReducer.
export const persistConfig = {
key: 'testApp',
version: 0, //New version 0, default or previous version -1
storage,
debug: true,
stateReconciler: autoMergeLevel2,
migrate: createMigrate(migrations, { debug: true })
}
Важно обновить версию до 0, чтобы она переместила наше хранилище с –1 до 0.
Далее мы пишем миграцию, чтобы наше хранилище знало, что есть обновление.
const migrations = {
0: (state) => {
return { ...
state,
tyre: { ...
state.tyre,
owner: { ...
state.tyre.owner,
details: {
state.tyre.owner.details,
address: "CA" //New Key added for migration
}
}
}
}
}
}
The миграции затем используются в нашей конфигурации сохранения, упомянутой выше:
migrate: createMigrate(migrations, { debug: true })
Таким образом, когда мы перезагружаем нашу программу, она проходит фазу согласования, где хранилище синхронизируется с недавно обновленным редуктором.
Вывод
Приведенная выше конфигурация всегда будет обновлять приложение на стороне клиента, когда вы выпускаете новые версии. Очень важно, чтобы мы были осторожны с этим, создавая первые офлайн-программы.
Это просто, если вы поймете основную концепцию и технику выполнения. Надеюсь, эта статья помогла вам понять важность управления версиями ваших состояний в хранилище.
Следите за мной твиттер чтобы получать больше обновлений относительно новых статей и быть в курсе последних разработок интерфейса. Также поделитесь этой статьей в Twitter, чтобы помочь другим узнать ее. Делиться – это забота ^_^.
Некоторые полезные ресурсы
- https://github.com/rt2zz/redux-persist/blob/master/docs/api.md
- https://medium.com/@clrksanford/persist-ence-is-key-using-redux-persist-to-store-your-state-in-localstorage-ac6a000aee63
- https://medium.com/async-la/redux-persist-your-state-7ad346c4dd07