मैं रिफ़क्स राज्य वृक्ष को कैसे ताज़ा कर सकता हूं?


92

Redux प्रलेखन का पहला प्रमुख है:

आपके पूरे एप्लिकेशन की स्थिति को एक एकल स्टोर के भीतर ऑब्जेक्ट ट्री में संग्रहीत किया जाता है।

और मैंने वास्तव में सोचा था कि मैं सभी प्रिंसिपलों को अच्छी तरह से समझता हूं। लेकिन मैं अब भ्रमित हूँ कि आवेदन का क्या मतलब है।

यदि आवेदन का अर्थ है कि वेबसाइट में बस एक छोटा सा जटिल हिस्सा है और सिर्फ एक पृष्ठ में काम करता है, तो मैं समझता हूं। लेकिन क्या होगा अगर आवेदन का मतलब पूरी वेबसाइट है? क्या मुझे राज्य का पेड़ रखने के लिए लोकलस्टोरेज या कुकी या कुछ का उपयोग करना चाहिए? लेकिन क्या होगा अगर ब्राउज़र लोकलस्टोरीज का समर्थन नहीं करता है?

मैं जानना चाहता हूं कि डेवलपर्स अपने राज्य के पेड़ को कैसे रखते हैं! :)


2
यह एक व्यापक प्रश्न है। आपके द्वारा बताई गई कोई भी चीज आप कर सकते हैं। क्या आपके पास वह कोड है जिसे आप हमें दिखाने के लिए साझा करना चाहेंगे कि आपने क्या प्रयास किया और क्या काम नहीं किया? आप अपनी संपूर्ण वेबसाइट को एकल इकाई होने के लिए कार्यान्वित कर सकते हैं, या आपके पास कई हो सकते हैं। आप डेटा को बनाए रखने के लिए लोकलस्टोरेज का उपयोग कर सकते हैं, या वास्तविक डीबी, या न ही। आवेदन का अर्थ है जीवित, सक्रिय उदाहरण। ज्यादातर मामलों में यह सिर्फ एक है, आपकी जड़। लेकिन, फिर से, अनुप्रयोगों को लागू करने के कई तरीके हैं।
ज़ेकेरॉइड

जवाबों:


88

यदि आप एक ब्राउज़र रिफ्रेश में अपनी Redux स्थिति को जारी रखना चाहते हैं, तो Redux मिडलवेयर का उपयोग करके ऐसा करना सबसे अच्छा है। की जाँच करें redux-जारी रहती है और redux भंडारण मिडलवेयर। वे दोनों आपके Redux राज्य को संग्रहीत करने के एक ही कार्य को पूरा करने का प्रयास करते हैं ताकि इसे बचाया जा सके और इसे इच्छा पर लोड किया जा सके।

-

संपादित करें

यह कुछ समय हो गया है क्योंकि मैंने इस प्रश्न पर दोबारा गौर किया है, लेकिन यह देखते हुए कि अन्य (अधिक उत्तर दिए गए उत्तर) आपके स्वयं के समाधान को प्रोत्साहित करते हैं, मुझे लगा कि मैं फिर से इसका जवाब दूंगा।

इस संपादन के रूप में, पिछले छह महीनों के भीतर दोनों पुस्तकालयों को अपडेट किया गया है। मेरी टीम कुछ वर्षों से उत्पादन में रिड्यूस-फ़िनिश का उपयोग कर रही है और इसमें कोई समस्या नहीं है।

हालांकि यह एक साधारण समस्या की तरह लग सकता है, आप जल्दी से पाएंगे कि अपने स्वयं के समाधान को रोल करने से न केवल रखरखाव का बोझ होगा, बल्कि बग और प्रदर्शन के मुद्दों का परिणाम होगा। दिमाग में आने वाले पहले उदाहरण हैं:

  1. JSON.stringifyऔर JSON.parseजरूरत पड़ने पर न केवल प्रदर्शन को चोट पहुंचा सकते हैं, बल्कि त्रुटियों को भी फेंक सकते हैं जब कोड के एक महत्वपूर्ण टुकड़े में अनहेल्दी हो जाता है जैसे कि आपका Redux स्टोर आपके एप्लिकेशन को क्रैश कर सकता है।
  2. (नीचे दिए गए उत्तर में आंशिक रूप से उल्लेख किया गया है): अपने ऐप राज्य को बचाने और पुनर्स्थापित करने के लिए कब और कैसे पता लगाना एक सरल समस्या नहीं है। इसे बहुत बार करें और आप प्रदर्शन को प्रभावित करेंगे। पर्याप्त नहीं है, या यदि राज्य के गलत हिस्सों को बरकरार रखा जाता है, तो आप खुद को अधिक बग के साथ पा सकते हैं। ऊपर उल्लिखित पुस्तकालयों को उनके दृष्टिकोण में युद्ध-परीक्षण किया गया है और उनके व्यवहार को अनुकूलित करने के कुछ सुंदर मूर्ख-प्रूफ तरीके प्रदान किए गए हैं।
  3. रेडक्स की सुंदरता का हिस्सा (विशेषकर रिएक्ट इकोसिस्टम में) इसकी क्षमता कई वातावरणों में रखी जा सकती है। इस संपादन के रूप में, redux-persist में 15 अलग-अलग स्टोरेज कार्यान्वयन हैं , जिसमें वेब के लिए भयानक स्थानीयफ़ोरम लाइब्रेरी शामिल है, साथ ही रिएक्ट नेटिव, इलेक्ट्रॉन और नोड के लिए समर्थन भी शामिल है।

इसे योग करने के लिए , 3kB मिनिफ़ाइज्ड + gzipped (इस एडिट के समय) के लिए यह कोई समस्या नहीं है, मैं अपनी टीम से खुद को हल करने के लिए कहूंगा।


5
मैं redux-persist की सिफारिश कर सकता हूं (अभी तक redux-storage की कोशिश नहीं की है) लेकिन यह मेरे लिए बहुत कम कॉन्फ़िगरेशन और सेटअप के साथ बहुत अच्छा काम करता है।
लैरीडाहोस्टर

इस तिथि तक दोनों पुस्तकालयों की सीम मृत हो जाती है और अंतिम समय के साथ 2 साल पहले की तरह बनी रहती है।
अनीब

1
Redux-persist जैसा दिखता है, थोड़ा पीछे
हटता है


2
इस जानकारी के बारे में इस पर ध्यान दें: वास्तविकता यह है कि सॉफ्टवेयर और पुस्तकालयों ने आम तौर पर समुदाय (समर्थन) आधारित दृष्टिकोण को अपनाया है कि प्रोग्रामिंग भाषा के कुछ बहुत ही महत्वपूर्ण मॉड्यूल तीसरे पक्ष / पुस्तकालयों द्वारा समर्थित हैं। आमतौर पर, डेवलपर को यह जानने के लिए अपने स्टैक में उपयोग किए जाने वाले हर उपकरण पर नज़र रखनी होती है कि क्या वह अपदस्थ / अद्यतन हो रहा है या नहीं। दो विकल्प; 1. अपने स्वयं के लागू करें और प्रदर्शन और क्रॉस प्लेटफॉर्म मानकों को सुनिश्चित करने के लिए हमेशा विकसित रहें। 2. युद्ध-परीक्षण किए गए समाधान का उपयोग करें और केवल @ MiFreidgeimSO- stopbeingevil के रूप में अपडेट / सिफारिशों की जांच करें
Geek Guy

80

25-अगस्त -2019 संपादित करें

जैसा कि एक टिप्पणी में कहा गया है। मूल रिडक्स-स्टोरेज पैकेज को प्रतिक्रिया-स्टैक में स्थानांतरित कर दिया गया है । यह दृष्टिकोण अभी भी अपने स्वयं के राज्य प्रबंधन समाधान को लागू करने पर केंद्रित है।


मूल उत्तर

जबकि प्रदान किया गया उत्तर कुछ बिंदु पर मान्य था, यह ध्यान रखना महत्वपूर्ण है कि मूल रिडक्स-स्टोरेज पैकेज को हटा दिया गया है और अब इसे बनाए नहीं रखा जा रहा है ...

पैकेज रिड्यूस-स्टोरेज के मूल लेखक ने परियोजना को अपदस्थ करने का निर्णय लिया है और अब इसे बनाए नहीं रखा गया है।

अब, यदि आप भविष्य में इस तरह की समस्याओं से बचने के लिए अन्य पैकेजों पर निर्भरता नहीं रखना चाहते हैं, तो अपने स्वयं के समाधान को रोल करना बहुत आसान है।

आपको बस इतना करना है:

1- एक ऐसा फंक्शन बनाएं जो राज्य को वापस लौटाए localStorageऔर फिर राज्य को createStoreस्टोर को हाइड करने के लिए दूसरे पैरामीटर में 's redux' फंक्शन पास करे।

 const store = createStore(appReducers, state);

2- राज्य परिवर्तन के लिए सुनो और हर बार राज्य बदलता है, राज्य को बचाओ localStorage

store.subscribe(() => {
    //this is just a function that saves state to localStorage
    saveState(store.getState());
}); 

और यह बात है ... मैं वास्तव में उत्पादन में कुछ इसी तरह का उपयोग करता हूं, लेकिन कार्यों का उपयोग करने के बजाय, मैंने नीचे एक बहुत ही सरल वर्ग लिखा है ...

class StateLoader {

    loadState() {
        try {
            let serializedState = localStorage.getItem("http://contoso.com:state");

            if (serializedState === null) {
                return this.initializeState();
            }

            return JSON.parse(serializedState);
        }
        catch (err) {
            return this.initializeState();
        }
    }

    saveState(state) {
        try {
            let serializedState = JSON.stringify(state);
            localStorage.setItem("http://contoso.com:state", serializedState);

        }
        catch (err) {
        }
    }

    initializeState() {
        return {
              //state object
            }
        };
    }
}

और फिर जब आपके ऐप को बूटस्ट्रैप कर रहा हो ...

import StateLoader from "./state.loader"

const stateLoader = new StateLoader();

let store = createStore(appReducers, stateLoader.loadState());

store.subscribe(() => {
    stateLoader.saveState(store.getState());
});

आशा है कि यह किसी की मदद करता है

प्रदर्शन नोट

यदि आपके एप्लिकेशन में राज्य परिवर्तन बहुत अक्सर होते हैं, तो स्थानीय स्टोरेज को सहेजना भी अक्सर आपके एप्लिकेशन के प्रदर्शन को नुकसान पहुंचा सकता है, खासकर यदि राज्य ऑब्जेक्ट ग्राफ़ को क्रमबद्ध करने / डिसेरलाइज़ करने के लिए बड़ा है। इन मामलों में, आप debounce करना चाहते हैं या समारोह का उपयोग कर localStorage करने के लिए राज्य की बचत होती है न रुके हो सकता है RxJs, lodashया कुछ इसी तरह।


11
मिडलवेयर का उपयोग करने के बजाय, मैं इस दृष्टिकोण को पसंद करता हूं। प्रदर्शन की चिंता के साथ सुझावों के लिए धन्यवाद।
जो झोउ

1
निश्चित रूप से पसंदीदा उत्तर। हालाँकि, जब मैं पृष्ठ को रिफ्रेश करता हूं और यह स्टोर बनाते समय लोकलस्टोरेज से स्टेट को लोड करता है, तो मुझे कई चेतावनियां मिलती हैं, जिसमें पिछले स्टेट में पाए गए टेक्स्ट "अनपेक्षित प्रॉपर्टीज [कंटेनर नेम] शामिल हैं, जो रिड्यूसर को मिला है। इसके बजाय ज्ञात reducer संपत्ति के नाम: "वैश्विक", "भाषा"। अप्रत्याशित गुणों को अनदेखा किया जाएगा। यह अभी भी काम करता है, और मूल रूप से शिकायत कर रहा है कि स्टोर बनाने के बिंदु पर यह उन सभी अन्य कंटेनरों के बारे में नहीं जानता है। इस चेतावनी के आसपास का रास्ता?
ज़ीफ़

@ कहना मुश्किल है। संदेश "लगता है" काफी स्पष्ट है, रिड्यूसर उन गुणों की अपेक्षा कर रहे हैं जो निर्दिष्ट नहीं हैं। यह क्रमबद्ध स्थिति में डिफ़ॉल्ट मान प्रदान करने से संबंधित कुछ हो सकता है?
लियो

बहुत सीधा समाधान है। धन्यवाद।
इशरा ​​मडवा

1
@ जोज़ो को सुनकर अच्छा लगेगा कि आप इस दृष्टिकोण को क्यों पसंद करते हैं। व्यक्तिगत रूप से, यह ऐसा लगता है जैसे सटीक बात के लिए मिडलवेयर का इरादा था।
michaelgmcd

2

यह लियो के उत्तर पर आधारित है (जो किसी भी तीसरे पक्ष के काम का उपयोग किए बिना प्रश्न के उद्देश्य को प्राप्त करने के बाद से स्वीकृत उत्तर होना चाहिए)।

मैंने एक सिंगलटन क्लास बनाया है जो एक Redux स्टोर बनाता है, इसे स्थानीय स्टोरेज का उपयोग करके बनाए रखता है और एक गेट्टर के माध्यम से अपने स्टोर तक सरल पहुंच की अनुमति देता है

इसका उपयोग करने के लिए, बस अपने मुख्य वर्ग के चारों ओर निम्नलिखित Redux- प्रदाता तत्व डालें:

// ... Your other imports
import PersistedStore from "./PersistedStore";

ReactDOM.render(
  <Provider store={PersistedStore.getDefaultStore().store}>
    <MainClass />
  </Provider>,
  document.getElementById('root')
);

और अपनी परियोजना में निम्न वर्ग जोड़ें:

import {
  createStore
} from "redux";

import rootReducer from './RootReducer'

const LOCAL_STORAGE_NAME = "localData";

class PersistedStore {

  // Singleton property
  static DefaultStore = null;

  // Accessor to the default instance of this class
  static getDefaultStore() {
    if (PersistedStore.DefaultStore === null) {
      PersistedStore.DefaultStore = new PersistedStore();
    }

    return PersistedStore.DefaultStore;
  }

  // Redux store
  _store = null;

  // When class instance is used, initialize the store
  constructor() {
    this.initStore()
  }

  // Initialization of Redux Store
  initStore() {
    this._store = createStore(rootReducer, PersistedStore.loadState());
    this._store.subscribe(() => {
      PersistedStore.saveState(this._store.getState());
    });
  }

  // Getter to access the Redux store
  get store() {
    return this._store;
  }

  // Loading persisted state from localStorage, no need to access
  // this method from the outside
  static loadState() {
    try {
      let serializedState = localStorage.getItem(LOCAL_STORAGE_NAME);

      if (serializedState === null) {
        return PersistedStore.initialState();
      }

      return JSON.parse(serializedState);
    } catch (err) {
      return PersistedStore.initialState();
    }
  }

  // Saving persisted state to localStorage every time something
  // changes in the Redux Store (This happens because of the subscribe() 
  // in the initStore-method). No need to access this method from the outside
  static saveState(state) {
    try {
      let serializedState = JSON.stringify(state);
      localStorage.setItem(LOCAL_STORAGE_NAME, serializedState);
    } catch (err) {}
  }

  // Return whatever you want your initial state to be
  static initialState() {
    return {};
  }
}

export default PersistedStore;

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.