আমি আমার রাজ্য গাছের কিছু অংশ লোকাল স্টোরেজে চালিয়ে যেতে চাই। এটি করার উপযুক্ত জায়গাটি কী? রিডুসার বা অ্যাকশন?
আমি আমার রাজ্য গাছের কিছু অংশ লোকাল স্টোরেজে চালিয়ে যেতে চাই। এটি করার উপযুক্ত জায়গাটি কী? রিডুসার বা অ্যাকশন?
উত্তর:
রিডিউসার এটি করার জন্য কখনই উপযুক্ত জায়গা নয় কারণ হ্রাসকারীদের খাঁটি হওয়া উচিত এবং এর কোনও পার্শ্ব প্রতিক্রিয়া নেই।
আমি এটি কেবল গ্রাহক হয়ে করার পরামর্শ দিচ্ছি:
store.subscribe(() => {
// persist your state
})
স্টোর তৈরি করার আগে, এই অবিরাম অংশগুলি পড়ুন:
const persistedState = // ...
const store = createStore(reducer, persistedState)
আপনি যদি ব্যবহার করেন তবে combineReducers()
খেয়াল করবেন যে রাজ্যটি প্রাপ্তি হ্রাসকারীরা তাদের ডিফল্ট state
আর্গুমেন্ট মানটি স্বাভাবিক হিসাবে "বুট আপ" করবে । এটি বেশ সহজ হতে পারে।
আপনি আপনার গ্রাহককে ডাবনো করা বাঞ্ছনীয় তাই আপনি লোকালস্টোরারে খুব দ্রুত লিখবেন না, বা আপনার পারফরম্যান্সে সমস্যা হবে।
অবশেষে, আপনি একটি মিডলওয়্যার তৈরি করতে পারেন যা বিকল্প হিসাবে এটি encapsulates, তবে আমি একটি গ্রাহক দিয়ে শুরু করব কারণ এটি একটি সহজ সমাধান এবং কাজটি ভালভাবে করে।
ড্যান আব্রামভের উত্তরের শূন্যস্থান পূরণ করতে আপনি এটি ব্যবহার করতে পারেন store.subscribe()
:
store.subscribe(()=>{
localStorage.setItem('reduxState', JSON.stringify(store.getState()))
})
স্টোরটি তৈরি করার আগে localStorage
আপনার কী এর অধীনে কোনও জেএসএনকে পরীক্ষা করে পার্স করুন:
const persistedState = localStorage.getItem('reduxState')
? JSON.parse(localStorage.getItem('reduxState'))
: {}
তারপরে আপনি এই persistedState
ধ্রুবকটি আপনার createStore
পদ্ধতিতে এভাবে পাস করুন :
const store = createStore(
reducer,
persistedState,
/* any middleware... */
)
persistedState
ফিরে আসা উচিত initialState
? অন্যথায় আমি মনে করি createStore
যে শূন্য বস্তুটি দিয়ে আরম্ভ করব।
এক কথায়: মিডওয়্যার
Redx-persist দেখুন । বা আপনার নিজের লিখুন।
[আপডেট 18 ডিসেম্বর 2016] একই রকম দুটি প্রকল্পের নিষ্ক্রিয়করণ বা নিষ্ক্রিয় করা এখন সরানোর জন্য সম্পাদিত।
উপরের সমাধানগুলি নিয়ে কারও যদি সমস্যা হয়, আপনি নিজের লিখতে পারেন। আমি কি করেছি তা আপনাকে দেখাতে দিন। saga middleware
বিষয়গুলিকে উপেক্ষা করুন কেবল দুটি জিনিস localStorageMiddleware
এবং reHydrateStore
পদ্ধতিতে ফোকাস করুন । localStorageMiddleware
টান সব redux state
এবং রাখে এটা local storage
এবং rehydrateStore
টান সব applicationState
স্থানীয় সংগ্রহস্থল যদি বর্তমান ও রাখে এটা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;
localStorage
স্টোরের কোনও কিছুই পরিবর্তিত না হয়েও কী এই লেখার প্রচুর ফলাফল হবে না ? অপ্রয়োজনীয় লেখার জন্য আপনি কীভাবে ক্ষতিপূরণ করবেন
আমি @ গ্রাডিজিকে উত্তর দিতে পারি না তবে তার কোডের ভিত্তিতে একটি বিকল্প হতে পারে:
const rootReducer = combineReducers({
users: authReducer,
});
const localStorageMiddleware = ({ getState }) => {
return next => action => {
const result = next(action);
if ([ ACTIONS.LOGIN ].includes(result.type)) {
localStorage.setItem(appConstants.APP_STATE, JSON.stringify(getState()))
}
return result;
};
};
const reHydrateStore = () => {
const data = localStorage.getItem(appConstants.APP_STATE);
if (data) {
return JSON.parse(data);
}
return undefined;
};
return createStore(
rootReducer,
reHydrateStore(),
applyMiddleware(
thunk,
localStorageMiddleware
)
);
পার্থক্যটি হ'ল আমরা কেবল কিছু ক্রিয়াকলাপ সংরক্ষণ করছি, আপনি কেবলমাত্র আপনার রাজ্যের শেষ ইন্টারঅ্যাকশনটি সংরক্ষণ করতে কোনও ডেবিউন ফাংশন ব্যবহার করতে পারেন event
আমি কিছুটা দেরি করেছি তবে আমি এখানে বর্ণিত উদাহরণ অনুসারে একটি অবিরাম রাষ্ট্র বাস্তবায়ন করেছি। আপনি যদি প্রতি এক্স সেকেন্ডের মধ্যে রাষ্ট্রটি আপডেট করতে চান তবে এই পদ্ধতি আপনাকে সহায়তা করতে পারে:
একটি মোড়ক ফাংশন সংজ্ঞায়িত করুন
let oldTimeStamp = (Date.now()).valueOf()
const millisecondsBetween = 5000 // Each X milliseconds
function updateLocalStorage(newState)
{
if(((Date.now()).valueOf() - oldTimeStamp) > millisecondsBetween)
{
saveStateToLocalStorage(newState)
oldTimeStamp = (Date.now()).valueOf()
console.log("Updated!")
}
}
আপনার গ্রাহকের একটি মোড়ক ফাংশন কল করুন
store.subscribe((state) =>
{
updateLocalStorage(store.getState())
});
এই উদাহরণে, রাষ্ট্র আপডেট করা হয় সর্বাধিক প্রতিটি 5 সেকেন্ড নির্বিশেষে কত ঘন ঘন একটি আপডেট সূত্রপাত হয়।
(state) => { updateLocalStorage(store.getState()) }
মধ্যে lodash.throttle
ভালো: store.subscribe(throttle(() => {(state) => { updateLocalStorage(store.getState())} }
এবং যুক্তিবিদ্যা ভিতরে পরীক্ষণ সময় মুছে ফেলুন।
অন্যান্য উত্তরগুলিতে (এবং জাম ক্রিনিসিয়ার মাঝারি নিবন্ধ ) সরবরাহিত দুর্দান্ত পরামর্শ এবং সংক্ষিপ্ত কোডের অংশগুলির উপর ভিত্তি করে এখানে একটি সম্পূর্ণ সমাধান!
আমাদের দুটি ফাংশন সমন্বিত একটি ফাইল দরকার যা স্থানীয় সঞ্চয়স্থানে / থেকে রাষ্ট্রটিকে / সঞ্চয় করে:
// FILE: src/common/localStorage/localStorage.js
// Pass in Redux store's state to save it to the user's browser local storage
export const saveState = (state) =>
{
try
{
const serializedState = JSON.stringify(state);
localStorage.setItem('state', serializedState);
}
catch
{
// We'll just ignore write errors
}
};
// Loads the state and returns an object that can be provided as the
// preloadedState parameter of store.js's call to configureStore
export const loadState = () =>
{
try
{
const serializedState = localStorage.getItem('state');
if (serializedState === null)
{
return undefined;
}
return JSON.parse(serializedState);
}
catch (error)
{
return undefined;
}
};
এই ফাংশনগুলি store.js দ্বারা আমদানি করা হয় যেখানে আমরা আমাদের স্টোরটি কনফিগার করি:
দ্রষ্টব্য: আপনার একটি নির্ভরতা যুক্ত করতে হবে: npm install lodash.throttle
// FILE: src/app/redux/store.js
import { configureStore, applyMiddleware } from '@reduxjs/toolkit'
import throttle from 'lodash.throttle';
import rootReducer from "./rootReducer";
import middleware from './middleware';
import { saveState, loadState } from 'common/localStorage/localStorage';
// By providing a preloaded state (loaded from local storage), we can persist
// the state across the user's visits to the web app.
//
// READ: https://redux.js.org/recipes/configuring-your-store
const store = configureStore({
reducer: rootReducer,
middleware: middleware,
enhancer: applyMiddleware(...middleware),
preloadedState: loadState()
})
// We'll subscribe to state changes, saving the store's state to the browser's
// local storage. We'll throttle this to prevent excessive work.
store.subscribe(
throttle( () => saveState(store.getState()), 1000)
);
export default store;
স্টোরটি index.js এ আমদানি করা হয় যাতে এটি সরবরাহকারীর কাছে যেতে পারে যা App.js কে গুটিয়ে দেয় :
// FILE: src/index.js
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import App from './app/core/App'
import store from './app/redux/store';
// Provider makes the Redux store available to any nested components
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
নোট করুন যে নিখুঁত আমদানিগুলির জন্য আপনার প্রজেক্টফোল্ডার / jsconfig.json- এ এই পরিবর্তন দরকার - এটি প্রথমে যদি ফাইলগুলি না খুঁজে পায় তবে এটি কোথায় সন্ধান করতে হবে তা এটি বলে। অন্যথায়, আপনি এসআরসি-র বাইরে থেকে কিছু আমদানির চেষ্টা করার বিষয়ে অভিযোগগুলি দেখতে পাবেন ।
{
"compilerOptions": {
"baseUrl": "src"
},
"include": ["src"]
}