Redux持久化及其持久化失效之刷新页面数据会重置问题解决

今天做项目练习,遇到很头疼的一件事情,那就是在做一个react-redux的持久化的时候,给我搞崩溃了,明明很简单的操作,硬是给我留下深刻教训,代码不良习惯的啦~
所以我必须记录下来,我觉得肯定有道友会遇见跟我一样的问题doge!
那先来讲讲redux的持久化,众所周知,redux就是类似全局状态管理但是又个人感觉稍微工序复杂但是也很强大的一个东西,因为其提供了connect和provider两个高阶组件,方便了数据和修改数据函数在外部组件的调用,那么为什么要扯上持久化呢,举个例子,你开发一个软件,但是涉及一个变量, 你不希望你的初始值在被用户刷新页面之后重置为默认值,一个很典型的场景就是坐标选择,用户选择将默认值广州选到北京,然后刷新页面,用户肯定不希望刚刚选择的北京又被重置为广州,造成不好的用户体验,所以,我们就必须使用持久化,那么localstorage很牛的道友也可以自己模仿一个咯,反正个性化嘛,不是cookie就是localstorage,但是有持久化库的,那就是redux-persist,哎呀扯远了,先讲讲怎么持久化:
首先,下载redux-presist

npm i redux-persist 

在redux的主页面(一般会命名为store.js)引入两个关键的类:

//导入持久化
import {
    
     persistStore,persistReducer } from 'redux-persist'
import storage  from 'redux-persist/lib/storage'

然后开始设置:主要包括后续你要加入到localstorage的名字,白名单也就是需要持久化那个模块,还要导入经过封装的storage,然后将reducer包装成持久化的,进而使用上述持久化后的reducer来创建store,然后持久化store,最后暴露出store和持久化store

const persistConfig={
    
        //持久化到本地的目录名称key值
    key:'xjd',
    storage,
    whitelist:['city']
}
const reducer=combineReducers({
    
    
    Tarbar,
    city,
    createcinemas
})

const persistedReducer=persistReducer(persistConfig,reducer)   //持久化reducer

const store = createStore(persistedReducer,applyMiddleware(thunk,promise));

const persistor=persistStore(store)

export {
    
    store,persistor}

最后一步在项目的index.js页面使用持久化,需要事先导入高阶组件PersistGate和redux主页面的两个类,然后包裹根组件即可:

import {
    
    store,persistor} from "./text-js/appxjd/redux/store"; 
import {
    
     PersistGate } from "redux-persist/integration/react";

const root=createRoot(document.getElementById('root'))
root.render(
    //引入react-redux的第一步
    <Provider store={
    
    store}>  
        <PersistGate loading={
    
    null} persistor={
    
    persistor}>
        <First></First>
        </PersistGate>
    </Provider>)

到这里,我们的持久化就是算完成了!

接下来看bug

有些道友会发现需要持久化的地方在刷新页面后一直重置,并没有生效,然后就一直不理解,毕竟这个东西包装过,想要看懂也比较那啥,但是!别忘记依旧是使用localstorage底层的,代码被重置那肯定是因为处理的函数哪个地方被重复执行。有了这个理论,经过我的不屑查找~找到了:

const cityreducer=function(prevState={
    
    
    cityname:'广州'
},action){
    
    
    var newstate={
    
    ...prevState}
    switch(action.type)
    {
    
    
        case 'change-city':
        newstate.cityname=action.value
        return newstate;
        default:
            return newstate
    }
}
export default cityreducer

看吼,上面的代码中,我将初始状态结构到一个新的对象,然后我在default中直接导出新的对象,但是持久化中,会将每次的state都判断一次,那如果你返回的是自己的newstate,那就不是redux持久化到你本地的那一个,因为那个东西就是prestate,然后你将他解构出来,相对于走一遍初始化,导出新的对象,所以持久化就会在每次刷新页面的时候不断使用新的对象去导入本地,也就形成不断刷新页面,数据跟着重置的现象,修改后成功解决:

const cityreducer=function(prevState={
    
    
    cityname:'广州'
},action){
    
    
    var newstate={
    
    ...prevState}
    switch(action.type)
    {
    
    
        case 'change-city':
        newstate.cityname=action.value
        return newstate;
        default:
            return prevState   //问题在这里得到解决
    }
}
export default cityreducer

最后,大家写redux的时候,状态如果没有修改,就不要返回新的解构对象吧,那个新对象是因为数据修改才返回的,为了避免不必要且不好找的bug,建议default一律采用返回prevstate~
好,今天的文章就到这里!

猜你喜欢

转载自blog.csdn.net/weixin_51295863/article/details/132921017
今日推荐