You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redux持久化数据刷新后丢失问题求助

Redux数据刷新后无法持久化问题

发帖前已查阅多篇论坛帖子,但仍未找到解决方案。使用Redux存储数据,页面导航时SignIn.js中存储的数据可正常保留,但刷新页面后数据丢失。尝试添加或移除白名单参数,均未解决问题。

persistStorage.js

import { configureStore } from '@reduxjs/toolkit';
import { persistStore, persistCombineReducers } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import authReducer from './authStorage'

const persistConfig = {
  key: 'root',
  storage,
  serializableCheck: {
    ignoredActions: ['SOME_ACTION'], 
    warnOnly: true,
  }
};


const persistedReducer = persistCombineReducers(persistConfig, authReducer);
const store = configureStore({
  reducer: persistedReducer
});

export const persistor = persistStore(store);

authStorage.js

import { createSlice } from '@reduxjs/toolkit';

const initialState = {
  token: "",
  id: ""
};

const authSlice = createSlice({
  name: 'auth',
  initialState,
    reducers: {
      setToken(state, action) {
        state.token = action.payload;
      },
      setID(state, action) {
        state.id = action.payload;
      },
      clear(state) {
        state.token = null;
        state.id = null;
      },
  },
});

SignIn.js

export const { setToken, setID, clear } = authSlice.actions;
export default authSlice.reducer;

import { useState, useRef } from "react";
import { useMutation } from "@apollo/client";
import { useNavigate } from "react-router-dom";
import { useCookies } from "react-cookie";

import Header from '../components/Header';
import InputField from "../components/InputField";

import { useDispatch, useSelector } from 'react-redux';

import { auth } from "../../index";
import { setToken, setID } from '../../authStorage';

import { SIGN_IN } from "../../queries/accountQueries.js";

import "../../style/signIn.css";

function SignIn() {
    const [email, setEmail] = useState("");
    const [password, setPassword] = useState("");

    const [ signIn, { data, loading, error }] = useMutation(SIGN_IN);
    const [ cookies, setCookie ] = useCookies(['session'])
    
    const navigate = useNavigate();
    const dispatch = useDispatch();

    let signedIn = useRef(false);

    const setValue = (newValue, valueType) => {
        if (valueType === "Email") setEmail(newValue);
        else setPassword(newValue);
    }
    
    if (loading) return <p>Loading...</p>; 
    else if (error) {
        alert("error");
        return <p>Error :({JSON.stringify(error, null, 2)}</p>;
    }
    else if (data != undefined && !signedIn.current) {
        signedIn.current = true

        dispatch(setToken(data.employeeSignIn.auth)); // stores data with Redux
        dispatch(setID(data.employeeSignIn.id));

        auth.signInKey = null;

        setCookie("session", data.employeeSignIn.session, {
            options: {
                maxAge: 7200
            }
        })

        navigate('/two-factor-auth');
    }
     return( 
        <>
            <Header view={false} />

            <div className="content centered flex col">
                <form className="centered" onSubmit={(e) => {
                    e.preventDefault();

                    auth.signInKey = process.env.REACT_APP_SIGN_IN_KEY;

                    signIn({
                        variables: {
                            email: email,
                            password: password
                        }
                    })
                }}>
                    <h2>Sign in</h2>
                    <InputField label="Email" value={email} onChangeState={setValue} />
                    <InputField type="password" label="Password" value={password} onChangeState={setValue} />
                    <input type="submit" className="button centered"/>
                </form>
            </div>
        </>
    )
}

export default SignIn;

index.js

root.render(
  <ApolloProvider client={client}>
      <Provider store={store}>
        <PersistGate loading={null} persistor={persistor}>
            <RouterProvider router={router} />
          </PersistGate>
      </Provider>
  </ApolloProvider>
);

已查阅相关帖子

  • React Native中使用Redux持久化存储
  • Redux-persist白名单传入reducer名称无效
  • React Native应用刷新或关闭后Redux-persist无法保存状态

解决方案

问题出在persistCombineReducers的使用方式上,你直接传入了单个authReducer,但该方法要求第二个参数是reducer映射对象,而非单个reducer。

修复步骤:

  1. 修改persistStorage.js
    将persistCombineReducers的第二个参数改为包含auth reducer的对象:

    const persistedReducer = persistCombineReducers(persistConfig, { auth: authReducer });
    

    这样redux-persist才能正确识别并持久化auth模块的状态。

  2. 可选:添加白名单(按需)
    如果只想持久化auth模块,可在persistConfig中添加白名单:

    const persistConfig = {
      key: 'root',
      storage,
      whitelist: ['auth'], // 指定要持久化的reducer名称
      serializableCheck: {
        ignoredActions: ['SOME_ACTION'], 
        warnOnly: true,
      }
    };
    
  3. 确认其他配置无误
    你的index.js中PersistGate包裹RouterProvider的逻辑是正确的,确保persistor已正确传入即可。

原因说明

persistCombineReducers需要通过reducer映射对象来关联持久化配置与对应模块,之前直接传入单个reducer会导致redux-persist无法正确跟踪状态,刷新后自然丢失数据。

内容的提问来源于stack exchange,提问作者mfusco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 14:55:58