redux
umi中使用dva替代了redux,对其的二次封装
这是全局的modal,如何处理state中的内容刷新丢失问题
思路:要解决强刷新浏览器导致state丢失的问题,可以将state存储在浏览器的sessionStorage中。当页面重新加载时,从sessionStorage中读取state并更新到应用程序中。
export default {
namespace: "counter",
state: {
count: 0,
token: "",
},
reducers: {
add(state: {count: number}) {
return {count: state.count + 1};
},
minus(state: {count: number}) {
return {count: state.count - 1};
},
setToken(state: any, {payload: token}: any) {
return {...state, token};
},
updateData(state, {payload}) {
return {...state, ...payload};
},
},
effects: {
*saveData({payload}, {put, select}) {
yield put({type: "updateData", payload});
const data = yield select((state: any) => state.counter);
sessionStorage.setItem("counterData", JSON.stringify(data));
},
},
subscriptions: {
setup({dispatch, history}) {
const data = sessionStorage.getItem("counterData");
if (data) {
dispatch({type: "saveData", payload: JSON.parse(data)});
}
// 监听 window.beforeunload 事件
window.addEventListener("beforeunload", () => {
dispatch({type: "saveData"});
});
},
},
};
代码解读:
- 在
effects
中添加saveData
方法,它用于将当前state中的数据保存到sessionStorage中。使用yield put
更新数据,然后用yield select
获取更新后的数据,最后将其保存到localStorage。 - 在
subscriptions
中添加setup
方法,该方法在应用启动时执行。在这里,从sessionStorage读取数据,如果存在数据,则通过调用saveData
方法将其更新到state中。 - 在需要保存state的地方,调用
saveData
方法。例如,在reducers中处理数据更新后,可以调用saveData
将更新后的数据保存到sessionStorage中。
通过以上步骤,即使在强刷新浏览器时,也可以从sessionStorage中恢复state数据,从而解决了state丢失的问题。
如果存在localStorage中可能需要关闭浏览器时是做清空处理
// 监听 window.unload 事件
window.addEventListener('unload', () => {
localStorage.clear();
});
只要是想关闭浏览器后清空localStorage见:关闭浏览器后清除localStorage的内容
vuex
思路:在页面刷新前将Vuex里的数据保存到 sessionStorage 中,进入应用时再从 sessionStorage 中取出数据并替换 store 的state,还原之前的状态;在Redux中也同理。
/**
* 缓存Vuex里的数据,解决页面刷新Vuex数据丢失问题
* @param {*} type 缓存方式 sessionStorage 和 localStorage ,默认是sessionStorage
*/
export function cacheVuex(store, type = sessionStorage) {
if (type.getItem('_store')) {
store.replaceState(
Object.assign({}, store.state, JSON.parse(type.getItem('_store')))
);
}
window.addEventListener('beforeunload', () => {
type.setItem('_store', JSON.stringify(store.state));
});
}