在使用React框架构建单页应用时,页面刷新后状态丢失是一个常见的问题。对于使用MobX作为状态管理的单页应用,解决这一问题尤为关键。以下是几种可行的解决方案:
一、浏览器本地存储
1. localStorage/sessionStorage
localStorage是浏览器提供的一种持久化存储方式,可以将状态数据保存在客户端,即使页面刷新或关闭浏览器,数据依然存在。sessionStorage与localStorage类似,但其数据仅在当前会话中有效,关闭浏览器标签页后数据会被清空。使用这两个storage进行状态持久化的步骤如下:
- 页面刷新前保存状态数据:在页面即将刷新时,将MobX store中的状态数据序列化为JSON字符串,并存储到localStorage/sessionStorage中。
import React from 'react'; import { observer } from 'mobx-react'; import { observable, action, computed, useStrict } from 'mobx'; class Store { @observable data = {}; @action getDataFromSessionStorage = () => { let data; const dataStr = sessionStorage.getItem('mobxState'); if (!dataStr) { data = {}; } else { data = JSON.parse(dataStr); } this.data = data; } @action onChange = (data) => { this.data = data; this.setDataToSessionStorage(data); } @action setDataToSessionStorage = (data) => { const dataStr = JSON.stringify(data); sessionStorage.setItem('mobxState', dataStr); } } let i = 0; const store = new Store(); @observer export default class Test extends React.Component { componentDidMount() { store.getDataFromSessionStorage(); } render() { const { data, onChange } = store; return ( <div> <p>{JSON.stringify(data)}</p> <button onClick={() => onChange({ key: i++, data: Math.random() })}>change</button> </div> ); } }
二、MobX Persist Store
MobX Persist Store是一个轻量级的工具,专门用于将MobX store中的观测值持久化到浏览器的本地存储中,并在页面重新加载后自动恢复。使用MobX Persist Store的步骤如下:
- 安装MobX Persist Store:
yarn add mobx-persist-store # 或者 npm i mobx-persist-store
- 在MobX store中使用makePersistable:
在这个例子中,import { makeAutoObservable } from 'mobx'; import { makePersistable } from 'mobx-persist-store'; export class SampleStore { someProperty = []; constructor() { makeAutoObservable(this); makePersistable(this, { name: 'SampleStore', properties: ['someProperty'], storage: window.localStorage, }); } }
makePersistable
会自动处理store的持久化和恢复工作。
三、React Router和React Context结合使用
如果你的单页应用使用了React Router,可以结合React Context来管理一些全局状态。通过Context提供者提供全局状态,并在整个应用中共享。这样,在页面刷新时,Context中的状态仍然存在:
- 创建Context和Provider:
import { createContext, useContext } from 'react'; const AppContext = createContext(); export const AppProvider = ({ children }) => { const appStore = useStore(); return <AppContext.Provider value={appStore}>{children}</AppContext.Provider>; }; export const useAppStore = () => useContext(AppContext);
- 在应用的顶层组件中使用AppProvider:
import { AppProvider } from './path-to-your-context-file'; const App = () => { return ( <AppProvider> {/* 其他组件 */} </AppProvider> ); }; export default App;
- 在需要访问全局状态的组件中使用useAppStore:
import { useAppStore } from './path-to-your-context-file'; const MyComponent = () => { const appStore = useAppStore(); // 使用appStore中的状态 };
四、IndexedDB
IndexedDB是一个更高级的浏览器存储方案,适合存储大量结构化数据。使用IndexedDB进行状态持久化的步骤如下:
- 创建和打开数据库:
const openRequest = indexedDB.open('myDatabase', 1); openRequest.onupgradeneeded = (event) => { const db = event.target.result; db.createObjectStore('stateStore'); };
- 保存状态数据到IndexedDB:
const saveStateToDB = (state) => { const transaction = db.transaction(['stateStore'], 'readwrite'); const store = transaction.objectStore('stateStore'); store.put(state, 'mobxState'); };
- 从IndexedDB恢复状态数据:
const loadStateFromDB = () => { const transaction = db.transaction(['stateStore'], 'readonly'); const store = transaction.objectStore('stateStore'); const request = store.get('mobxState'); request.onsuccess = () => { const state = request.result; mobxStore = new MobXStore(state); }; };
五、服务器端存储
将状态数据保存到服务器端数据库中,也是一种可行的持久化方案。在页面刷新前,将状态数据发送到服务器进行存储;在页面加载时,从服务器获取状态数据并恢复:
- 页面刷新前发送状态数据到服务器:
window.addEventListener('beforeunload', () => { fetch('/save-state', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(mobxStore), }); });
- 页面加载时从服务器获取状态数据:
fetch('/get-state') .then((response) => response.json()) .then((state) => { mobxStore = new MobXStore(state); });
以上几种方案各有优缺点,可以根据实际需求和应用规模选择合适的方法。对于简单的应用,使用localStorage或MobX Persist Store可能更方便快捷;而对于需要存储大量数据或需要跨设备同步的应用,IndexedDB或服务器端存储可能更为合适。
标签:状态,const,单页,解决方案,MobX,data,store,页面 From: https://www.cnblogs.com/little-sheep10/p/18652147