簡體   English   中英

如何跨頁面刷新維護React / Redux應用程序的狀態?

[英]How to maintain the state of React/Redux application across page refreshes?

我是新來的反應js。

我有兩條路線,如A和B.現在我將一些值從A傳遞給B作為道具。 如果刷新B頁面,則A中的所有道具值都將消失,B頁面不會呈現。 我正在使用與redux的反應。

mapDispatchToPropsmapStateToProps函數用於將A和B路由之間的值作為props傳遞。

例如:路由A已完成一些計算並將值存儲在redux狀態,路由B通過使用mapStateToProps導出為connect(mapStateToProps, mapDispatchToProps)(B) ,其中A的狀態值作為props傳遞給B。

請建議我在上述用例上處理瀏覽器刷新的最佳方法,以及在路由之間傳遞值的任何其他最佳方法。 提前致謝。

您的問題涉及兩個不同的問題。 首先是在React / Redux應用程序中將props從一個頁面傳遞到另一個頁面,其次是在刷新頁面時維護應用程序狀態。

您已經描述了在基於redux的應用程序中在兩個路由之間傳遞數據的正確方法。

這讓我們想到了第二個問題。
刷新頁面時如何維護React / Redux應用程序的狀態?

當刷新React / Redux應用程序時,它會再次初始化並且redux存儲獲取它的默認值。

如果您希望跨頁刷新或跨不同會話維護應用程序狀態,則需要將狀態存儲在某個位置,並在應用程序初始化時加載它。

我們可以將這個問題分為三個部分:

  • 存儲數據的位置
  • 如何存儲redux狀態
  • 初始化應用程序時如何重新加載數據

讓我們分別看一下每個子問題。

存儲數據的位置?

您可以使用Web Storage API在用戶的瀏覽器中存儲數據。 此API提供了2種存儲數據的機制:

  • sessionStorage:只要瀏覽器處於打開狀態,就會保留存儲的數據,包括頁面重新加載和恢復。
  • localStorage:數據一直保留,直到用戶或應用程序清除為止。 即使瀏覽器已關閉並重新打開,它仍然存在。

sessionStoragelocalStorage都允許您在瀏覽器中存儲鍵值對,並且兩者都提供相同的功能集來管理數據。

對於sessionStorage(從MDN獲取的示例):

// Save data to sessionStorage
window.sessionStorage.setItem('key', 'value');

// Get saved data from sessionStorage
var data = window.sessionStorage.getItem('key');

// Remove saved data from sessionStorage
window.sessionStorage.removeItem('key');

// Remove all saved data from sessionStorage
window.sessionStorage.clear();

對於localStorage:

// Save data to localStorage
window.localStorage.setItem('key', 'value');

// Get saved data from localStorage
var data = window.localStorage.getItem('key');

// Remove saved data from localStorage
window.localStorage.removeItem('key');

如何存儲redux狀態?

您已經知道,Redux提供了一個createStore函數,該函數使用root reducer並返回應用程序store

store對象包含整個應用程序商店,並提供一些方法,包括一個注冊監聽器的方法。

store.subscribe(listener)可用於向商店添加更改偵聽器,每次商店更新時都會調用該更改。

我們將向商店添加一個監聽器,它將應用程序狀態保存到localStorage

嘗試使用createStore在您創建商店的文件中添加:

/**
 * This function accepts the app state, and saves it to localStorage
 * @param state
 */
const saveState = (state) => {
    try {
        // Convert the state to a JSON string 
        const serialisedState = JSON.stringify(state);

        // Save the serialised state to localStorage against the key 'app_state'
        window.localStorage.setItem('app_state', serialisedState);
    } catch (err) {
        // Log errors here, or ignore
    }
};

/**
 * This is where you create the app store
 */
const store = createStore(rootReducer);

/**
 * Add a change listener to the store, and invoke our saveState function defined above.
 */
store.subscribe(() => {
    saveState(store.getState());
});

如何重新加載存儲的數據,並在應用程序再次初始化時恢復應用程序狀態?

當我們使用createStore創建我們的應用商店時,我們可以選擇使用函數的第二個參數將初始狀態傳遞給商店。

當應用程序啟動時,我們將檢查localStorage是否有任何已保存的數據。 如果我們找到它,我們將把它作為createStore的第二個參數發送。

這樣,當應用程序完成初始化時,它將具有與刷新頁面或關閉瀏覽器之前相同的狀態。

嘗試使用createStore在您創建商店的文件中添加:

/**
 * This function checks if the app state is saved in localStorage
 */
const loadState = () => {
    try {
        // Load the data saved in localStorage, against the key 'app_state'
        const serialisedState = window.localStorage.getItem('app_state');

        // Passing undefined to createStore will result in our app getting the default state
        // If no data is saved, return undefined
        if (!serialisedState) return undefined;

        // De-serialise the saved state, and return it.
        return JSON.parse(serialisedState);
    } catch (err) {
        // Return undefined if localStorage is not available, 
        // or data could not be de-serialised, 
        // or there was some other error
        return undefined;
    }
};

/**
 * This is where you create the app store
 */
const oldState = loadState();
const store = createStore(rootReducer, oldState);

而已! 現在,結合最后兩個代碼塊,您的應用程序可以跨頁面刷新維護狀態,甚至可以跨瀏覽器重新啟動。

希望這可以幫助。 干杯! :)

你可以嘗試redux-persistredux-storage ,當初始化存儲createStore(reducer, [preloadedState], [enhancer]) ,你可以獲取數據並將其分配給preloadedState

嘗試使用react-router ,這將基於route呈現組件。

initialized應用程序時,應用程序應獲取數據並使用所需信息更新商店。

例如:在下面的示例中,當IntilizeApp組件正在裝載時,計算所需的信息並通過調度操作來更新存儲。 使用react的生命周期方法,如componentWillMount來計算。

    import {Router, Route, hashHistory} from 'react-router'
    // import initializeApp
    // import ComponentA
    // import ComponentB

    <Router history={hashHistory}>
      <Route path="/" component={InitializeApp}>
        <Route name="A" path="A" component={ComponentA} />
        <Route name="B" path="B" component={ComponentB} />
      </Route>
    </Router>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM