# 📚 常用工具库使用指南 本文档介绍项目中已安装的常用工具库及其使用方法。 ## 📦 已安装的库列表 ### 工具类库 | 库名 | 版本 | 用途 | | ------------------- | -------- | ---------------------------------------- | | **lodash-es** | ^4.17.21 | JavaScript 工具函数库(ES modules 版本) | | **dayjs** | ^1.11.19 | 轻量级日期处理库 | | **axios** | ^1.13.1 | HTTP 请求库 | | **zustand** | ^5.0.8 | 轻量级状态管理 | | **react-hook-form** | ^7.66.0 | 表单处理库 | | **zod** | ^4.1.12 | TypeScript 数据验证库 | ### Expo 原生模块 | 库名 | 版本 | 用途 | | --------------------------------------------- | ------- | -------------- | | **@react-native-async-storage/async-storage** | ^2.2.0 | 本地存储 | | **expo-image** | ^3.0.10 | 优化的图片组件 | | **expo-haptics** | ^15.0.7 | 触觉反馈 | ### 开发工具 | 库名 | 版本 | 用途 | | -------------------- | -------- | ----------------------------- | | **@types/lodash-es** | ^4.17.12 | Lodash-ES TypeScript 类型定义 | --- ## 🚀 快速开始 ### 1. Lodash-ES - JavaScript 工具库 > **注意**:使用 `lodash-es` 而不是 `lodash`,支持 ES modules 和更好的 tree-shaking。 ```typescript // 推荐:按需导入(tree-shaking 友好) import { map, filter, uniq, pick, cloneDeep, debounce } from 'lodash-es'; // 数组操作 map([1, 2, 3], (n) => n * 2); // [2, 4, 6] filter([1, 2, 3, 4], (n) => n % 2 === 0); // [2, 4] uniq([1, 2, 2, 3]); // [1, 2, 3] // 对象操作 pick({ a: 1, b: 2, c: 3 }, ['a', 'b']); // { a: 1, b: 2 } cloneDeep(obj); // 深拷贝 // 防抖和节流 const handleSearch = debounce((text) => { console.log('Searching:', text); }, 300); // 也可以全量导入(不推荐,会增加包体积) import _ from 'lodash-es'; _.map([1, 2, 3], (n) => n * 2); ``` ### 2. Day.js - 日期处理 ```typescript import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; import 'dayjs/locale/zh-cn'; dayjs.extend(relativeTime); dayjs.locale('zh-cn'); // 格式化 dayjs().format('YYYY-MM-DD HH:mm:ss'); // 相对时间 dayjs().fromNow(); // '几秒前' dayjs().subtract(1, 'day').fromNow(); // '1天前' // 日期操作 dayjs().add(7, 'day'); // 7天后 dayjs().startOf('month'); // 本月第一天 ``` ### 3. Axios - HTTP 请求 ```typescript import axios from 'axios'; // 创建实例 const api = axios.create({ baseURL: 'https://api.example.com', timeout: 10000, }); // 请求拦截器 api.interceptors.request.use(async (config) => { const token = await AsyncStorage.getItem('token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }); // 使用 const data = await api.get('/users'); await api.post('/users', { name: 'John' }); ``` ### 4. Zustand - 状态管理 ```typescript import { create } from 'zustand'; interface UserState { user: User | null; setUser: (user: User) => void; } export const useUserStore = create((set) => ({ user: null, setUser: (user) => set({ user }), })); // 在组件中使用 const user = useUserStore((state) => state.user); const setUser = useUserStore((state) => state.setUser); ``` ### 5. React Hook Form + Zod - 表单处理 ```typescript import { useForm, Controller } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; const schema = z.object({ email: z.string().email('请输入有效的邮箱'), password: z.string().min(6, '密码至少6个字符'), }); type FormData = z.infer; function LoginForm() { const { control, handleSubmit, formState: { errors } } = useForm({ resolver: zodResolver(schema), }); const onSubmit = (data: FormData) => { console.log(data); }; return ( ( )} /> ); } ``` ### 6. AsyncStorage - 本地存储 ```typescript import AsyncStorage from '@react-native-async-storage/async-storage'; // 存储 await AsyncStorage.setItem('key', JSON.stringify(value)); // 读取 const value = await AsyncStorage.getItem('key'); const data = value ? JSON.parse(value) : null; // 删除 await AsyncStorage.removeItem('key'); // 清空 await AsyncStorage.clear(); ``` ### 7. Expo Image - 优化的图片组件 ```typescript import { Image } from 'expo-image'; ``` ### 8. Expo Haptics - 触觉反馈 ```typescript import * as Haptics from 'expo-haptics'; // 轻触反馈 Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); // 成功反馈 Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); // 错误反馈 Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error); ``` --- ## 💡 实用示例 ### 创建 API 工具类 ```typescript // utils/api.ts import axios from 'axios'; import AsyncStorage from '@react-native-async-storage/async-storage'; const api = axios.create({ baseURL: 'https://api.example.com', timeout: 10000, }); api.interceptors.request.use(async (config) => { const token = await AsyncStorage.getItem('token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }); api.interceptors.response.use( (response) => response.data, (error) => { if (error.response?.status === 401) { AsyncStorage.removeItem('token'); } return Promise.reject(error); } ); export default api; ``` ### 创建 Storage 工具类 ```typescript // utils/storage.ts import AsyncStorage from '@react-native-async-storage/async-storage'; class Storage { static async setObject(key: string, value: T): Promise { await AsyncStorage.setItem(key, JSON.stringify(value)); } static async getObject(key: string): Promise { const value = await AsyncStorage.getItem(key); return value ? JSON.parse(value) : null; } static async remove(key: string): Promise { await AsyncStorage.removeItem(key); } } export default Storage; ``` ### 创建用户状态管理 ```typescript // stores/userStore.ts import { create } from 'zustand'; import { persist, createJSONStorage } from 'zustand/middleware'; import AsyncStorage from '@react-native-async-storage/async-storage'; interface User { id: string; name: string; email: string; } interface UserState { user: User | null; setUser: (user: User) => void; clearUser: () => void; } export const useUserStore = create()( persist( (set) => ({ user: null, setUser: (user) => set({ user }), clearUser: () => set({ user: null }), }), { name: 'user-storage', storage: createJSONStorage(() => AsyncStorage), } ) ); ``` ### 日期格式化工具 ```typescript // utils/date.ts import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; import 'dayjs/locale/zh-cn'; dayjs.extend(relativeTime); dayjs.locale('zh-cn'); export const formatDate = (date: Date | string | number) => { return dayjs(date).format('YYYY-MM-DD HH:mm:ss'); }; export const formatRelativeTime = (date: Date | string | number) => { return dayjs(date).fromNow(); }; export const formatChatTime = (timestamp: number) => { const date = dayjs(timestamp); const now = dayjs(); if (date.isSame(now, 'day')) { return date.format('HH:mm'); } else if (date.isSame(now.subtract(1, 'day'), 'day')) { return '昨天 ' + date.format('HH:mm'); } else if (date.isSame(now, 'year')) { return date.format('MM-DD HH:mm'); } else { return date.format('YYYY-MM-DD'); } }; ``` --- ## 📝 最佳实践 1. **代码组织** - 将 API 配置放在 `utils/api.ts` - 将存储工具放在 `utils/storage.ts` - 将状态管理放在 `stores/` 目录 - 将验证规则放在 `schemas/` 目录 2. **性能优化** - 使用 `_.debounce` 和 `_.throttle` 优化频繁触发的事件 - 使用 Zustand 的选择器避免不必要的重渲染 - 使用 Expo Image 的缓存策略 3. **类型安全** - 使用 Zod 定义数据结构并自动生成 TypeScript 类型 - 为 Zustand store 定义完整的类型 - 使用 `@types/lodash` 获得完整的类型提示 4. **错误处理** - 在 Axios 拦截器中统一处理错误 - 使用 try-catch 包裹异步操作 - 提供用户友好的错误提示 --- ## 🔗 相关资源 - [Lodash 文档](https://lodash.com/docs/) - [Day.js 文档](https://day.js.org/) - [Axios 文档](https://axios-http.com/) - [Zustand 文档](https://zustand-demo.pmnd.rs/) - [React Hook Form 文档](https://react-hook-form.com/) - [Zod 文档](https://zod.dev/) - [AsyncStorage 文档](https://react-native-async-storage.github.io/async-storage/) - [Expo Image 文档](https://docs.expo.dev/versions/latest/sdk/image/) - [Expo Haptics 文档](https://docs.expo.dev/versions/latest/sdk/haptics/) --- **提示**:所有库都已安装并配置好,可以直接在项目中使用!🎉