Бібліотека Redux Persist для роботи з localstorage
При роботі з Redux не можна напряму звертатися до localStorage, оскільки ми не можемо бути однозначно впевнені, що отримаємо дані зі сховища раніше ніж, наприклад, буде зарендерено сторінку.
Кешування даних програми на стороні клієнта (у браузері) - одна з центральних тем frontend-розробки. Можна написати кастомну логіку middleware для роботи з state і localStorage або використовувати готову бібліотеку redux-persist, яка зробить це за нас.
Розглянемо порядок роботи з redux-persist.
Спочатку потрібно встановити пакет redux-persist
npm i redux-persistРобимо потрібні імпорти в наш store.js
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for webПеред нашим store вставляємо обʼєкт налаштувань persistConfig для persist.
const persistConfig = {
key: 'root',
storage,
}Тут root - назва ключа за яким в localStorage будуть зберігатися наші дані. Persist додасть свій префікс і ключ (в даному випадку називатиметься persist:root). Бажано назвати згідно з назвою параметра, який треба зберегти. Наприклад: value. Тоді в localStorage він називатиметься persist:value.
4. Коли із valueSlice ми імпортуємо редʼюсер, то після persistConfig проганяємо його через persistReducer.
import { valueReducer } from './valueSlice';const persistedValueReducer = persistReducer(persistConfig, valueReducer)Першим параметром передаємо файл конфігурації, другим - редʼюсер отриманий з valueSlice. І зберігаємо в нову змінну.
В нашому store міняємо редʼюсер на новий (на той який прогнали через persistReducer), який відповідає за параметр, який хочемо зберегти.
Нам також через persistStore потрібно прогнати весь наш store.
У нашому файлі index.js треба вказати, що ми використовуємо persist при роботі зі store. Для цього в index.js імпортуємо persistor зі store.js. А також імпортуємо PersistGate з 'redux-persist/integration/react'. Після цього весь наш головний компонент App огортаємо в PersistGate із параметрами loading={null} і persistor={persistor}.
Persist налаштовано. Але потрібно в правильному форматі зберігати дані в нашому параметрі value. Раніше в localStorage ми могли зберігати безпосередньо обʼєкт, масив, рядок, число, буль тощо (звичайно після прогонки його через JSON.stringify()). Persist же зберігає в localStorage обʼєкт (теж після JSON.stringify()). Перший параметр - буде наш ключ зазначений в persistConfig. Другий - параметр налаштувань _persist самого persist.
Розглянемо цей приклад. В localStorage зберігається обʼєкт з трьома параметрами: names, phones та totalSallary. Перші два це масиви, третій - рядок і плюс вкінці службовий параметр від самого persist.
В такому разі розглянемо формат об'єкта нашого параметра. На прикладі початкового значення initialState (якщо в localStorage уже чи ще нічого немає)
В такому разі коли ми захочемо у редʼюсері чи селекторі звертатися до якогось параметра всередині нашого стейта - робимо це через крапку і назву параметра. Відповідно: state.names state.phones. state.totalSallary.
За замовчанням всі параметри обʼєкта зберігатимуться в localStorage. Але ми можемо використовувати додаткові налаштування для вибору, що зберігати. Blacklist - додає якийсь параметр обʼєкта в виключення (збережуться всі крім нього), або Whitelist - перераховуємо тільки ті параметри, які плануємо зберігати в localStorage.
Рефакторинг коду
Як бачимо із вищезазначеного коду, що наш файл store містить інформацію, яка більше стосується редʼюсера, а не самого стетйту. Тому логічніше persistConfig і persistedReducer винести в файл slice і звідти його експортувати в store.js.
Нижче наведено код всіх повʼязаних файлів після рефакторингу
Внизу valueSlice.js бачимо експорти екшенів та селекторів. Їх ми уже безпосередньо використовуємо, коли звертаємося в компонентах до стейту.
Селектори використовуємо для того, щоб отримати в змінну значення стейту.
Екшени формують обʼєкт "завдання", яке до редʼюсера доправляє діспатч.
Посилання на офіційну документацію:
Last updated