Files
rn-app/stores/userStore.ts
2025-11-06 16:37:01 +08:00

162 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 用户状态管理
* 使用 Zustand + AsyncStorage 持久化
*/
import { create } from 'zustand';
import { useShallow } from 'zustand/react/shallow';
import AsyncStorage from '@react-native-async-storage/async-storage';
/**
* 用户信息接口
*/
export interface User {
id: string;
username: string;
email: string;
avatar?: string;
nickname?: string;
phone?: string;
createdAt?: string;
}
/**
* 用户状态接口
*/
interface UserState {
// 状态
user: User | null;
isLoggedIn: boolean;
token: string | null;
// 操作
setUser: (user: User) => void;
setToken: (token: string) => void;
login: (user: User, token: string) => void;
logout: () => void;
updateUser: (updates: Partial<User>) => void;
}
/**
* 用户状态 Store
*/
export const useUserStore = create<UserState>()((set, get) => ({
// 初始状态
user: null,
isLoggedIn: false,
token: null,
// 设置用户信息
setUser: (user) => {
const newState = { user, isLoggedIn: true };
set(newState);
// 手动持久化
AsyncStorage.setItem('user-storage', JSON.stringify(newState));
},
// 设置 token
setToken: (token) => {
set({ token });
// 手动持久化 - 延迟执行以确保状态已更新
setTimeout(() => {
const state = get();
AsyncStorage.setItem('user-storage', JSON.stringify(state));
}, 0);
},
// 登录
login: (user, token) => {
const newState = {
user,
token,
isLoggedIn: true,
};
set(newState);
// 同时保存 token 到 AsyncStorage用于 API 请求)
AsyncStorage.setItem('auth_token', token);
// 手动持久化整个状态
AsyncStorage.setItem('user-storage', JSON.stringify(newState));
if (__DEV__) {
console.log('✅ User logged in:', user.username);
}
},
// 登出
logout: () => {
const newState = {
user: null,
token: null,
isLoggedIn: false,
};
set(newState);
// 清除 AsyncStorage 中的 token
AsyncStorage.removeItem('auth_token');
// 清除持久化状态
AsyncStorage.removeItem('user-storage');
if (__DEV__) {
console.log('👋 User logged out');
}
},
// 更新用户信息
updateUser: (updates) => {
const currentUser = get().user;
if (currentUser) {
const newUser = { ...currentUser, ...updates };
set({ user: newUser });
// 手动持久化
AsyncStorage.setItem('user-storage', JSON.stringify({ ...get(), user: newUser }));
if (__DEV__) {
console.log('📝 User updated:', updates);
}
}
},
}));
// 从 AsyncStorage 恢复状态的函数
export const restoreUserState = async () => {
try {
const stored = await AsyncStorage.getItem('user-storage');
if (stored) {
const state = JSON.parse(stored);
useUserStore.setState(state);
if (__DEV__) {
console.log('✅ User state restored from storage');
}
}
} catch (error) {
console.error('Failed to restore user state:', error);
}
};
/**
* 选择器 Hooks优化性能避免不必要的重渲染
*/
// 获取用户信息
export const useUser = () => useUserStore((state) => state.user);
// 获取登录状态
export const useIsLoggedIn = () => useUserStore((state) => state.isLoggedIn);
// 获取 token
export const useToken = () => useUserStore((state) => state.token);
// 获取用户操作方法
// 使用 useShallow 避免每次渲染都返回新对象
export const useUserActions = () =>
useUserStore(
useShallow((state) => ({
setUser: state.setUser,
setToken: state.setToken,
login: state.login,
logout: state.logout,
updateUser: state.updateUser,
}))
);