本系列从零搭建一个后台系统,技术选型React18 + ReactRouter7 + Vite4 + Antd5 + zustand + TS。
这个系列文章将会从零开始,一步一步搭建一个后台系统,这个系统将会包括登录、权限、菜单、用户、角色等功能。
后台系统从零搭建(一)—— 项目基础
后台系统从零搭建(二)—— 系统架构设计1之路由封装
后台系统从零搭建(二)—— 系统架构设计2之Axios请求封装
后台系统从零搭建(二)—— 系统架构设计3之环境变量封装
后台系统从零搭建(二)—— 系统架构设计4之CSSModule、主题、登录页
后台系统从零搭建(二)—— 系统架构设计5之公共布局Layout
后台系统从零搭建(二)—— 系统架构设计6之zustand状态管理
后台系统从零搭建(二)—— 系统架构设计7之菜单和路由的关联
后台系统从零搭建(三)—— 具体页面之用户管理(通用的增删改查逻辑和form-render)
后台系统从零搭建(三)—— 具体页面之菜单管理和角色管理
后台系统从零搭建(三)—— 具体页面之部门管理(抽离通用的增删改查逻辑)
后台系统从零搭建(四)—— 终结篇之权限系统怎么设计-RBAC模式
本文主要介绍系统架构设计之zustand状态管理。
Zustand适合中小型项目或需要轻量级状态管理的场景, 其核心特点:
- 轻量级:API 简单,学习成本低。
- 高性能:支持选择性订阅,避免不必要的渲染。
- 灵活:支持异步操作、持久化、DevTools 等。
1.安装zustand
pnpm install zustand
2.创建store
在src/store目录下创建user.ts文件,用于存储用户信息。
// src/store/user.ts
import { create } from 'zustand'
import { apiGetUser, type IUserInfo } from '@/service/user'
type IUserState = {
user: IUserInfo
}
type IUserAction = {
setUser: (user: IUserInfo) => void
resetUser: () => void
fetchUser: () => Promise<void>
}
type IUserStore = IUserState & IUserAction
// 初始状态
const userInit: IUserInfo = {
name: '',
email: '',
}
// 创建 store
export const useUserStore = create<IUserStore>((set) => ({
user: { ...userInit },
setUser: (user) => set({ user }),
resetUser: () => set({ user: userInit }),
fetchUser: async () => {
try {
const res = await apiGetUser()
set({ user: res })
} catch (error) {
console.error('Failed to fetch user:', error)
}
},
}))
/**
* 使用的时候
* import { useUserStore } from '@/store/user'
* import { shallow } from 'zustand/shallow'
* // 只订阅 user 状态
* const user = useUserStore((state) => state.user)
* // 只订阅 setUser 方法
* const setUser = useUserStore((state) => state.setUser)
* // 订阅多个状态,使用 shallow 避免不必要的重渲染
* const { user, setUser } = useUserStore((state) => ({
* user: state.user,
* setUser: state.setUser,
* }))
* // 订阅所有状态
* const state = useUserStore()
*/
用户信息的api,因为是全局的所以放在src/service/user.ts中。
import request from '@/utils/request'
export type IUserInfo = {
id?: number
name: string
email: string
role?: string
_id?: string
deptId?: string
state?: number
roleList?: string[]
createId?: string
deptName?: string
mobile?: string
job?: string
avatar?: string
introduction?: string
username?: string
}
export const apiGetUser = (): Promise<IUserInfo> => {
return request.get('/api/userInfo')
}
export default {
apiGetUser,
}
3.获取用户信息,保存在store中
项目启动的时候,获取用户信息,保存在store中。
这边在App.tsx中获取用户信息。
import { useUserStore } from '@/store/user'
import { useEffect } from 'react'
function App() {
useEffect(() => {
const fetchUser = useUserStore((state) => state.fetchUser)
fetchUser()
}, [])
// ...
}
4.使用用户信息
在NavHeader组件中使用用户信息。
// src/layout/NavHeader/index.tsx
import { useUserStore } from '@/store/user'
import { shallow } from 'zustand/shallow'
// ...
const user = useUserStore((state) => state.user)
const resetUser = useUserStore((state) => state.resetUser)
const menuItems: MenuProps['items'] = [
{
label: '退出登录',
key: '1',
onClick: () => {
resetUser()
localStorage.setItem('token', '')
location.href = '/login?callback=' + encodeURIComponent(location.href)
},
},
]
// 下面的name和email就是替换成用户信息