جافاسكريبت - أين يمكن الكتابة إلى localStorage في تطبيق Redux؟
أريد الاحتفاظ ببعض أجزاء شجرة الحالة الخاصة بي في التخزين المحلي. ما هو المكان المناسب للقيام بذلك؟ المُخفّض أم الإجراء؟
الإجابة رقم 1
المخفض ليس مكانًا مناسبًا أبدًا للقيام بذلك لأن المخفضات يجب أن تكون نقية ولا تحتوي على تأثيرات جانبية.
أود أن أوصي ببساطة بفعله في مشترك:
store.subscribe(() => {
// persist your state
})
قبل إنشاء المتجر، اقرأ تلك الأجزاء المحفوظة:
const persistedState = // ...
const store = createStore(reducer, persistedState)
إذا استخدمت combineReducers() فستلاحظ أن الريديوسرات التي لم تتلقَ الحالة ستقوم بـ "التمهيد" كالمعتاد باستخدام القيمة الافتراضية لوسيط state الخاص بها. يمكن أن يكون هذا مفيدًا جدًا.
من المستحسن أن تقوم بإلغاء التكرار لمشتركك حتى لا تكتب في التخزين المحلي بسرعة كبيرة، وإلا ستواجه مشاكل في الأداء.
أخيرًا، يمكنك إنشاء وسيط برمجي يضم ذلك كبديل، لكني سأبدأ بمشترك لأنه حل أبسط ويؤدي المهمة بشكل جيد.
الإجابة رقم 2
لملء الفراغات في إجابة دان أبراموف، يمكنك استخدام store.subscribe() على هذا النحو:
store.subscribe(()=>{
localStorage.setItem('reduxState', JSON.stringify(store.getState()))
})
قبل إنشاء المتجر، تحقق من localStorage وحلل أي JSON تحت مفتاحك بهذا الشكل:
const persistedState = localStorage.getItem('reduxState')
? JSON.parse(localStorage.getItem('reduxState'))
: {}
ثم تقوم بتمرير هذا الثابت persistedState إلى طريقتك createStore بهذا الشكل:
const store = createStore(
reducer,
persistedState,
/* any middleware... */
)
الإجابة رقم 3
باختصار: البرمجيات الوسيطة.
اطلع على redux-persist. أو اكتب الخاص بك.
[تحديث 18 ديسمبر 2016] تم التعديل لإزالة ذكر مشروعين مشابهين أصبحا غير نشطين أو مهملين الآن.
الإجابة رقم 4
إذا كان لدى أي شخص أي مشكلة مع الحلول المذكورة أعلاه، يمكنك كتابة الحل الخاص بك أيضًا. دعني أريك ما فعلته. تجاهل أشياء saga middleware وركز فقط على شيئين localStorageMiddleware وreHydrateStore الطريقة. يقوم localStorageMiddleware بسحب كل حالة redux ووضعها في التخزين المحلي وreHydrateStore يسحب كل حالة التطبيق في التخزين المحلي إذا كانت موجودة ويضعها في redux store
import {createStore, applyMiddleware} from 'redux'
import createSagaMiddleware from 'redux-saga';
import decoristReducers from '../reducers/decorist_reducer'
import sagas from '../sagas/sagas';
const sagaMiddleware = createSagaMiddleware();
/**
* Add all the state in local storage
* @param getState
* @returns {function(*): function(*=)}
*/
const localStorageMiddleware = ({getState}) => { // <--- FOCUS HERE
return (next) => (action) => {
const result = next(action);
localStorage.setItem('applicationState', JSON.stringify(
getState()
));
return result;
};
};
const reHydrateStore = () => { // <-- FOCUS HERE
if (localStorage.getItem('applicationState') !== null) {
return JSON.parse(localStorage.getItem('applicationState')) // re-hydrate the store
}
}
const store = createStore(
decoristReducers,
reHydrateStore(),// <-- FOCUS HERE
applyMiddleware(
sagaMiddleware,
localStorageMiddleware,// <-- FOCUS HERE
)
)
sagaMiddleware.run(sagas);
export default store;
