状态管理
前言
在 React (也包括 Vue 等)中,状态管理非常重要,好用的状态管理框架能在大型的应用中, 轻松的在组件之间进行数据传递,无需进行 props 穿透。同时还有简化组件之间的代码逻辑,提高代码性能。
Zustand
在 AIFlowy 中,我们是使用 Zustand 进行状态管理的, Zustand 是一个简单且轻量级的状态管理库,它的设计非常简洁,是 Redux 最佳的替代方案。目前已经有 51k 的 star。
示例代码
定义 Store 的数据类型
typescript
export interface AppStore {
nickName?: string,
avatar?: string,
jwt?: string,
isLogin: () => boolean,
setLogin: (jwt: string, nickName: string) => void,
setNickname: (nickName: string) => void,
setAvatar: (avatar: string) => void,
setJwt: (jwt: string) => void,
logOut: () => void,
}
通过 Zustand 创建 Store
typescript
export const useAppStore = create<AppStore>()(persist(
(set, get) => ({
nickName: '',
avatar: '',
jwt: '',
isLogin: () => {
const token = get().jwt;
if (!token) {
return false;
}
const tokenParts = token.split('.');
if (tokenParts.length != 3) {
return false;
}
const payload = tokenParts[1];
try {
const {exp} = JSON.parse(window.atob(payload))
return Date.now() < exp * 1000;
} catch (e) {
return false;
}
},
setLogin: (jwt: string, nickName: string) => {
localStorage.setItem(authKey, jwt)
set({nickName: nickName, jwt: jwt})
},
setNickname: (nickName: string) => {
set({nickName: nickName})
},
setAvatar: (avatar: string) => {
set({avatar: avatar})
},
setJwt: (jwt: string) => {
localStorage.setItem(authKey, jwt)
set({jwt: jwt})
},
logOut: () => {
localStorage.removeItem(authKey)
set({nickName: '', avatar: '', jwt: ''})
},
}), {
name: "custom-store",
storage: createJSONStorage(() => localStorage)
})
)
使用 Store
在使用 store 方面,涉及两个部分:
- 1 修改 store 的数据
- 2 监听 store 的数据变化
在 AIFlowy 中,有一个名称为 Setting.tsx
的页面组件,用于修改用户的资料,修改成功后会更新 store 的数据,代码如下:
typescript
const store = useAppStore();
const onFinish: FormProps['onFinish'] = (values) => {
doPost({
data: values
}).then(resp => {
if (resp.data.errorCode == 0) {
//更新 store 的数据
store.setNickname(values.nickname as string)
message.success("个人资料修改成功!")
}
})
};