با کمک کتابخانه redux-persist میتوان حالات برنامه را در مرورگر ذخیره کرد
موقعی که از ریداکس استفاده میکنیم، با هر بار رفرش صفحه، مقادیر state های ریداکس از حافظه رم پاک میشوند. ابزار redux-persist به ما کمک میکند، مقادیر stateهای redux را در جایی مانند localstorage مرورگر ذخیره کنیم. با مراجعات بعدی کاربر به صفحه، این ابزار مقادیر ذخیره شده در ذخیرهگاه محلی مرورگر را، به کاربر نمایش میدهد.
برای این مقاله من یک شمارنده ایجاد شده است :
حالت شروع یا initialState برنامه :
const initialState = { loading:true, counter:0, nightMode: false, }
اعمال کننده یا reducer برنامه :
import initialState from '../initialState' import {State} from '../initialState' function reducer ( state:State=initialState , action:any ){ switch (action.type){ case 'COUNTER_UP': const counter = state.counter; return { ...state, counter:counter+1, } default: return state; } }
با هر ارسال اکشن COUNTER_UP به store ، مقدار شمارنده یک واحد افزایش مییابد.
اکنون میتوانیم store را ایجاد کنیم :
import { legacy_createStore as createStore,Store, applyMiddleware} from 'redux'; import initialState from './initialState'; import reducer from './reducer'; const store:Store = createStore( reducer, initialState );
export {store};
اکنون میتوانیم در اپ خود از store استفاده کنیم :
import ReactDOM from 'react-dom/client'; import { Provider } from 'react-redux/es/exports'; import App from './App'; import {store} from './store'; const root = ReactDOM.createRoot( document.getElementById('root') as HTMLElement ); root.render( <Provider store={store}> <App /> </Provider> );
برای دریافت مقدارهای state ریداکس و همچنین ارسال اکشن به store در کامپوننت App.js
import { useSelector } from 'react-redux' import { useDispatch } from 'react-redux/es/exports' function App() { const counter = useSelector((state)=>state.counter); const dispatch = useDispatch(); const counterUp = () => { dispatch({type:'COUNTER_UP'}); } return (<> <h1>{counter}</h1> <button ={counterUp}>counter up</button> </>); } export default App;
نتیجه کار تا اینجا :
همینطور که درون تصویر مشخص است، با هر بار رفرش مرورگر، مقدار شمارنده پاک میشود.
برای اضافه کردن redux-persist به پروژه جاوااسکریپت خود فقط کافیست دستور زیر را در ترمینال وارد کنیم.
npm install redux-persist
برای استفاده از redux-persisit نیازی به ایجاد تغییر در reducer و اکشنها نداریم. فقط کافیست درون فایل store تغییرات کوچکی ایجاد کنیم، ابتدا نیاز به یک تعیین persistConfig برای redux-persist داریم :
آبجکت persistConfig ، مجموعهای از پراپرتیهای از پیش مشخص شده است.
import storage from 'redux-persist/lib/storage'; // defaults to localStorage for web const persistConfig = { key: 'root', storage: storage, blacklist: ['loading'] };
پراپرتی key :کلید دسترسی به محتوای ذخیره شده است.
پراپرتی storage : محل ذخیره حالات برنامه را تعیین میکند، برای استفاده در محیط وب، معمولا از localstorage استفاده میشود.
برای استفاده از redux-persist مقداردهی storage و key الزامی است ولی سایر پراپرتیها اختیاری میباشد.
پراپرتی blacklist : لیست state هایی که نمیخواهیم در localstorage ذخیره شوند را مشخص میکنیم.
پراپرتی whitelist : برعکس blacklist، لیست stateهایی که میخواهیم در localstorage ذخیره شوند را مشخص میکند.
import storage from 'redux-persist/lib/storage'; // defaults to localStorage for web const persistConfig = { key: 'root', storage: storage, blacklist: ['nightMode','counter'] };
فقط یکی از پراپرتیهای blacklist و یا whitelist را مقدار دهی میکنیم.
پراپرتی version : نسخه state را مشخص میکند. برای زمانی که برنامه خود را آپدیت میکنیم میتواند مفید باشد.
پراپرتی debog : مقدار boolean دریافت میکند و مشخص میکند که همزمان با تغییرات log در کنسول ثبت شود یا خیر!
پراپرتی stateReconciler : نحوه تطبیق دادن state ها را مشخص میکند.
باید ابتدا reducer پایه خود را به کمک تابع persistReducer ، برای استفاده در استور به persistedReducer تبدیل کنیم و سپس آنرا به createStore بجای reducer پاس دهیم.
import reducer from './reducer'; import { persistReducer } from 'redux-persist'; import storage from 'redux-persist/lib/storage'; const persistConfig = { key:'root', storage, blacklist:['loading'], } const persistedReducer = persistReducer( persistConfig , reducer ); const store:Store = createStore( persistedReducer, );
اکنون با استفاده از store میتوان persistor مناسب را ایجاد کرد:
import persistStore from 'redux-persist/es/persistStore'; const persistor = persistStore(store);
برای استفاده در برنامه باید persistor را همراه با استور export کرد :
export {store , persistor};
فایل کامل store.js :
import { legacy_createStore as createStore,Store, applyMiddleware} from 'redux'; import reducer from './reducer'; import { persistReducer } from 'redux-persist'; import storage from 'redux-persist/lib/storage'; import persistStore from 'redux-persist/es/persistStore'; const persistConfig = { key:'root', storage:storage, blacklist:['loading'] } const persistedReducer = persistReducer( persistConfig , reducer ); const store:Store = createStore( persistedReducer, ); const persistor = persistStore(store); export {store , persistor};
برای استفاده از persistor باید برنامه خود را بوسیله کامپوننت PersistGate بپوشانیم، و مقدار persistor را بعنوان props به آن پاس دهیم :
import ReactDOM from 'react-dom/client'; import { Provider } from 'react-redux/es/exports'; import App from './App'; import {persistor, store} from './store'; import { PersistGate } from 'redux-persist/integration/react'; const root = ReactDOM.createRoot( document.getElementById('root') as HTMLElement ); root.render( <Provider store={store}> <PersistGate persistor={persistor}> <App /> </PersistGate> </Provider> );
اکنون تغییرات حالات برنامه در storage ذخیره میشود و با رفرش صفحه به آن دسترسی خواهیم داشت. خروجی برنامه به این شکل است :