From 8f2980f07f430eb2bbc9d853862df86d231abb6a Mon Sep 17 00:00:00 2001 From: ZLY Date: Thu, 18 Sep 2025 11:49:52 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E5=B0=86react-redux=E7=9A=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=BF=81=E7=A7=BB=E8=87=B3redux-toolkit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/NavBar/index.tsx | 14 ++++----- src/components/Settings/block.tsx | 15 ++++------ src/components/Settings/color.tsx | 8 ++--- src/pages/_app.tsx | 16 +++------- src/store/index.ts | 49 ++++++++++++++++++------------- 5 files changed, 46 insertions(+), 56 deletions(-) diff --git a/src/components/NavBar/index.tsx b/src/components/NavBar/index.tsx index ec4fa03..e687ae7 100644 --- a/src/components/NavBar/index.tsx +++ b/src/components/NavBar/index.tsx @@ -20,6 +20,7 @@ import useStorage from '@/utils/useStorage'; import { generatePermission } from '@/routes'; import logoImage from '@/public/assets/logo.png'; import useUser from '@/hooks/user'; +import { updateUserInfo } from '@/store'; function Navbar({ show }: { show: boolean }) { const t = useLocale(); @@ -42,15 +43,12 @@ function Navbar({ show }: { show: boolean }) { } useEffect(() => { - dispatch({ - type: 'update-userInfo', - payload: { - userInfo: { - ...userInfo, - permissions: generatePermission(role) - } + dispatch(updateUserInfo({ + userInfo: { + ...userInfo, + permissions: generatePermission(role) } - }); + })); }, [role]); if (!show) { diff --git a/src/components/Settings/block.tsx b/src/components/Settings/block.tsx index 6cecc2a..17955f1 100644 --- a/src/components/Settings/block.tsx +++ b/src/components/Settings/block.tsx @@ -4,6 +4,7 @@ import { useSelector, useDispatch } from 'react-redux'; import { GlobalState } from '../../store'; import useLocale from '../../utils/useLocale'; import styles from './style/block.module.less'; +import { updateSettings } from '@/store'; export interface BlockProps { title?: ReactNode; @@ -34,12 +35,9 @@ export default function Block(props: BlockProps) { onChange={(checked) => { const newSetting = { ...settings, - [option.value]: checked, + [option.value]: checked }; - dispatch({ - type: 'update-settings', - payload: { settings: newSetting }, - }); + dispatch(updateSettings({ settings: newSetting })); // set color week if (checked && option.value === 'colorWeek') { document.body.style.filter = 'invert(80%)'; @@ -58,12 +56,9 @@ export default function Block(props: BlockProps) { onChange={(value) => { const newSetting = { ...settings, - [option.value]: value, + [option.value]: value }; - dispatch({ - type: 'update-settings', - payload: { settings: newSetting }, - }); + dispatch(updateSettings({ settings: newSetting })); }} /> )} diff --git a/src/components/Settings/color.tsx b/src/components/Settings/color.tsx index ef259ba..4aaaedc 100644 --- a/src/components/Settings/color.tsx +++ b/src/components/Settings/color.tsx @@ -6,6 +6,7 @@ import { useSelector, useDispatch } from 'react-redux'; import { GlobalState } from '../../store'; import useLocale from '@/utils/useLocale'; import styles from './style/color-panel.module.less'; +import { updateSettings } from '@/store'; function ColorPanel() { const theme = @@ -26,13 +27,10 @@ function ColorPanel() { color={themeColor} onChangeComplete={(color) => { const newColor = color.hex; - dispatch({ - type: 'update-settings', - payload: { settings: { ...settings, themeColor: newColor } }, - }); + dispatch(updateSettings({ settings: { ...settings, themeColor: newColor } })); const newList = generate(newColor, { list: true, - dark: theme === 'dark', + dark: theme === 'dark' }); newList.forEach((l, index) => { const rgbStr = getRgbStr(l); diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 5817617..08fe5f9 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -3,15 +3,12 @@ import { useRouter } from 'next/router'; import cookies from 'next-cookies'; import Head from 'next/head'; import type { AppProps } from 'next/app'; -import { createStore } from 'redux'; import { Provider } from 'react-redux'; import '../style/global.less'; import { ConfigProvider, Message } from '@arco-design/web-react'; import zhCN from '@arco-design/web-react/es/locale/zh-CN'; import enUS from '@arco-design/web-react/es/locale/en-US'; -import axios from 'axios'; import NProgress from 'nprogress'; -import rootReducer from '../store'; import { GlobalContext } from '../context'; import checkLogin from '@/utils/checkLogin'; import '@/api'; // 全局挂载axios拦截器 @@ -21,8 +18,9 @@ import Layout from './layout'; import '../mock'; import { getUserInfo } from '@/api/user'; import { setSessionUserInfo } from '@/utils/auth'; +import store from '@/store'; // 只导入 store +import { updateUserInfo } from '@/store'; // 导入 action -const store = createStore(rootReducer); interface RenderConfig { arcoLang?: string; @@ -51,16 +49,10 @@ export default function MyApp({ }, [lang]); async function fetchUserInfo() { - store.dispatch({ - type: 'update-userInfo', - payload: { userLoading: true } - }); + store.dispatch(updateUserInfo({ userLoading: true })); const res: any = await getUserInfo(); setSessionUserInfo(res.data); - store.dispatch({ - type: 'update-userInfo', - payload: { userInfo: { ...res.data } } - }); + store.dispatch(updateUserInfo({ userInfo: { ...res.data } })); } useEffect(() => { diff --git a/src/store/index.ts b/src/store/index.ts index 84f0e03..925cc62 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,4 +1,6 @@ +import { createSlice, configureStore } from '@reduxjs/toolkit'; import defaultSettings from '../settings.json'; + export interface GlobalState { settings?: typeof defaultSettings; userInfo?: { @@ -16,28 +18,33 @@ export interface GlobalState { const initialState: GlobalState = { settings: defaultSettings, userInfo: { - permissions: {}, - }, + permissions: {} + } }; -export default function store(state = initialState, action) { - switch (action.type) { - case 'update-settings': { - const { settings } = action.payload; - return { - ...state, - settings, - }; +const globalSlice = createSlice({ + name: 'global', + initialState, + reducers: { + updateSettings(state, action) { + state.settings = action.payload.settings; + }, + updateUserInfo(state, action) { + state.userInfo = action.payload.userInfo || initialState.userInfo; + state.userLoading = action.payload.userLoading; } - case 'update-userInfo': { - const { userInfo = initialState.userInfo, userLoading } = action.payload; - return { - ...state, - userLoading, - userInfo, - }; - } - default: - return state; } -} +}); + +// 保持与原来相同的 action creators 导出方式 +export const { updateSettings, updateUserInfo } = globalSlice.actions; + +// 创建 store +const store = configureStore({ + reducer: globalSlice.reducer +}); + +export type RootState = ReturnType; +export type AppDispatch = typeof store.dispatch; + +export default store;