页面刷新后通知复选框Redux状态重置问题咨询
解决复选框刷新后状态重置的问题
你的问题核心是Redux状态存储在内存中,页面刷新后会回到初始值,同时当前代码存在几个细节问题,以下是具体解决方案:
1. 页面加载时主动拉取用户最新通知设置
目前你的代码只有更新设置的逻辑,没有初始化获取设置的步骤,导致刷新后Redux状态回到initialState里的false。需要新增获取用户通知设置的逻辑:
修改userProfileSlice.js
添加获取通知设置的action和reducer,同时修复更新时重置状态的问题:
import { createSlice } from '@reduxjs/toolkit'; const initialState = { updateNotificationSettings: { error: false, success: false, fetch: false, message: '', comms_optin_email: false, }, }; export const userProfileSlice = createSlice({ name: 'userProfile', initialState, reducers: { // 新增:开始获取通知设置 fetchNotificationSettingsStarted: state => { state.updateNotificationSettings = { ...state.updateNotificationSettings, fetch: true, error: false, }; }, // 新增:获取通知设置成功 fetchNotificationSettingsFinished: (state, action) => { state.updateNotificationSettings = { ...state.updateNotificationSettings, fetch: false, comms_optin_email: action.payload, }; }, // 新增:获取通知设置失败 fetchNotificationSettingsFailed: (state, action) => { state.updateNotificationSettings = { ...state.updateNotificationSettings, fetch: false, error: true, message: action.payload, }; }, // 修改原有的updateStarted,不要重置comms_optin_email updateNotificationSettingsStarted: state => { state.updateNotificationSettings = { ...state.updateNotificationSettings, error: false, success: false, fetch: true, message: '', }; }, updateNotificationSettingsFinished: (state, action) => { state.updateNotificationSettings = { error: false, success: true, fetch: false, message: '', comms_optin_email: action.payload, }; }, updateNotificationSettingsFailed: (state, action) => { state.updateNotificationSettings = { error: true, success: false, fetch: false, message: action.payload, }; }, }, }); // 导出新增的action export const { fetchNotificationSettingsStarted, fetchNotificationSettingsFinished, fetchNotificationSettingsFailed, updateNotificationSettingsStarted, updateNotificationSettingsFinished, updateNotificationSettingsFailed, } = userProfileSlice.actions; export default userProfileSlice.reducer;
修改NotificationSettingsPage.js
在组件挂载时触发获取逻辑,并同步Redux状态到本地:
import { useTranslation } from 'react-i18next'; import { useState, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { updateNotificationSettingsStarted, fetchNotificationSettingsStarted } from '../../../store/userProfileSlice'; import CommunicationPermisson from '../../AuthPages/CommunicationPermissionModal/CommunicationPermisson'; import NiceModal from '@ebay/nice-modal-react'; export default function NotificationSettingsPage() { const { t } = useTranslation(); const dispatch = useDispatch(); const { auth } = useSelector(state => state.auth); const { comms_optin_email } = useSelector( state => state.userProfile.updateNotificationSettings, ); const [isOffersChecked, setIsOffersChecked] = useState(comms_optin_email); const nanoid = auth?.user?.nanoid; // 组件挂载时拉取最新通知设置 useEffect(() => { if (nanoid) { dispatch(fetchNotificationSettingsStarted(nanoid)); } }, [dispatch, nanoid]); // 同步Redux状态到本地state useEffect(() => { setIsOffersChecked(comms_optin_email); }, [comms_optin_email]); const handleOffersClick = e => { e.preventDefault(); NiceModal.show(CommunicationPermisson); }; const handleFormSubmit = e => { e.preventDefault(); dispatch( updateNotificationSettingsStarted({ nanoid: nanoid, isOffersChecked: isOffersChecked, }), ); }; // 原有JSX代码保持不变 return ( <section aria-labelledby="payment-details-heading"> {/* ... 原有代码 ... */} </section> ); }
2. 可选:Redux状态持久化(避免频繁请求后端)
如果不想每次刷新都请求后端,可以用redux-persist将Redux状态存储到localStorage中,页面加载时自动恢复:
安装依赖
npm install redux-persist
配置store(假设你的store配置文件是store.js)
import { configureStore } from '@reduxjs/toolkit'; import { persistStore, persistReducer } from 'redux-persist'; import storage from 'redux-persist/lib/storage'; import userProfileReducer from './userProfileSlice'; import authReducer from './authSlice'; // 导入你的auth reducer const persistConfig = { key: 'root', storage, whitelist: ['userProfile'] // 只持久化userProfile模块 }; const persistedReducer = persistReducer(persistConfig, userProfileReducer); export const store = configureStore({ reducer: { userProfile: persistedReducer, auth: authReducer }, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false, // 关闭序列化检查避免报错 }), }); export const persistor = persistStore(store);
修改根组件(比如App.js)
import { Provider } from 'react-redux'; import { PersistGate } from 'redux-persist/integration/react'; import { store, persistor } from './store'; function App() { return ( <Provider store={store}> <PersistGate loading={null} persistor={persistor}> {/* 你的应用组件 */} </PersistGate> </Provider> ); } export default App;
内容的提问来源于stack exchange,提问作者Enes
相关产品推荐
相关产品推荐

