docs: 更新优惠券相关文档- 新增优惠券API集成文档

- 新增优惠券卡片对齐修复文档
- 新增优惠券状态显示调试文档
- 新增优惠券组件警告修复文档- 更新用ShopInfo Hook字段迁移文档
- 更新Arguments关键字修复文档
This commit is contained in:
2025-08-15 01:52:36 +08:00
parent dc87f644c9
commit 1b24a611a8
50 changed files with 6530 additions and 595 deletions

254
docs/INFINITE_LOOP_FIX.md Normal file
View File

@@ -0,0 +1,254 @@
# 🚨 useShopInfo 无限循环问题修复
## 问题描述
`useShopInfo` Hook 出现无限循环请求的问题,控制台不断输出 `shopInfo` 请求日志。
## 🔍 问题分析
### 根本原因
Hook中存在循环依赖导致的无限循环
```typescript
// 问题代码 ❌
const fetchShopInfo = useCallback(async (forceRefresh = false) => {
if (!forceRefresh && loadShopInfoFromStorage()) {
return shopInfo; // 依赖shopInfo
}
// ...
}, [shopInfo, loadShopInfoFromStorage, saveShopInfoToStorage]); // 依赖shopInfo
useEffect(() => {
fetchShopInfo(); // 依赖fetchShopInfo
}, [fetchShopInfo]); // 当fetchShopInfo变化时重新执行
```
### 循环链路
1. `useEffect` 依赖 `fetchShopInfo`
2. `fetchShopInfo` 依赖 `shopInfo`
3.`shopInfo` 更新时,`fetchShopInfo` 重新创建
4. `fetchShopInfo` 变化触发 `useEffect` 重新执行
5. `useEffect` 再次调用 `fetchShopInfo`
6. 无限循环 🔄
## 🔧 修复方案
### 1. **移除fetchShopInfo对shopInfo的依赖**
#### 修复前 ❌
```typescript
const fetchShopInfo = useCallback(async (forceRefresh = false) => {
// 如果不是强制刷新,先尝试从缓存加载
if (!forceRefresh && loadShopInfoFromStorage()) {
return shopInfo; // ❌ 依赖shopInfo导致循环
}
// ...
}, [shopInfo, loadShopInfoFromStorage, saveShopInfoToStorage]);
```
#### 修复后 ✅
```typescript
const fetchShopInfo = useCallback(async (forceRefresh = false) => {
try {
setLoading(true);
setError(null);
const data = await getShopInfo();
setShopInfo(data);
// 保存到本地存储
saveShopInfoToStorage(data);
return data;
} catch (error) {
// 错误处理...
} finally {
setLoading(false);
}
}, [saveShopInfoToStorage]); // ✅ 移除shopInfo依赖
```
### 2. **重构初始化逻辑**
#### 修复前 ❌
```typescript
useEffect(() => {
fetchShopInfo(); // ❌ 依赖fetchShopInfo导致循环
}, [fetchShopInfo]);
```
#### 修复后 ✅
```typescript
useEffect(() => {
const initShopInfo = async () => {
// 先尝试从缓存加载
const hasCache = loadShopInfoFromStorage();
// 如果没有缓存,则从服务器获取
if (!hasCache) {
await fetchShopInfo();
}
};
initShopInfo();
}, []); // ✅ 空依赖数组,只执行一次
```
### 3. **独立的刷新函数**
#### 修复前 ❌
```typescript
const refreshShopInfo = useCallback(() => {
return fetchShopInfo(true); // ❌ 依赖fetchShopInfo
}, [fetchShopInfo]);
```
#### 修复后 ✅
```typescript
const refreshShopInfo = useCallback(async () => {
try {
setLoading(true);
setError(null);
const data = await getShopInfo();
setShopInfo(data);
// 保存到本地存储
saveShopInfoToStorage(data);
return data;
} catch (error) {
// 错误处理...
} finally {
setLoading(false);
}
}, [saveShopInfoToStorage]); // ✅ 独立实现,避免循环依赖
```
## 📊 修复对比
| 项目 | 修复前 | 修复后 | 说明 |
|------|--------|--------|------|
| **fetchShopInfo依赖** | `[shopInfo, ...]` | `[saveShopInfoToStorage]` | 移除shopInfo依赖 |
| **useEffect依赖** | `[fetchShopInfo]` | `[]` | 只执行一次初始化 |
| **缓存检查** | 在fetchShopInfo中 | 在useEffect中 | 分离关注点 |
| **刷新函数** | 依赖fetchShopInfo | 独立实现 | 避免循环依赖 |
| **请求次数** | 无限循环 | 按需请求 | 性能优化 |
## ✅ 修复效果
### 修复前 ❌
```
🔄 无限循环请求
📊 控制台不断输出shopInfo日志
⚡ 性能问题,浪费网络资源
🐛 用户体验差,页面卡顿
```
### 修复后 ✅
```
✅ 只在需要时请求一次
📊 控制台日志正常
⚡ 性能优化,智能缓存
🚀 用户体验良好,页面流畅
```
## 🎯 Hook执行流程
### 修复后的正确流程
```
1. 组件挂载
2. useEffect执行只执行一次
3. 检查本地缓存
4. 如果有缓存 → 使用缓存数据,结束
5. 如果无缓存 → 调用fetchShopInfo
6. 获取数据,更新状态,保存缓存
7. 结束,不再重复请求
```
## 🧪 验证方法
### 1. **控制台检查**
- ✅ 不再有重复的shopInfo请求日志
- ✅ 只在初始化时请求一次
- ✅ 刷新时才会重新请求
### 2. **网络面板检查**
- ✅ Network面板中只有必要的请求
- ✅ 没有重复的/shop/getShopInfo请求
- ✅ 缓存机制正常工作
### 3. **功能验证**
- ✅ 商店信息正常显示
- ✅ Logo和网站名称正确
- ✅ 缓存机制工作正常
- ✅ 手动刷新功能正常
## 🛠️ 预防措施
### 1. **避免循环依赖**
```typescript
// ❌ 避免这样的依赖关系
const funcA = useCallback(() => {
// 使用stateB
}, [stateB]);
const funcB = useCallback(() => {
funcA();
}, [funcA]);
useEffect(() => {
funcB();
}, [funcB]);
```
### 2. **合理使用useCallback依赖**
```typescript
// ✅ 只依赖真正需要的值
const fetchData = useCallback(async () => {
// 不要在依赖数组中包含会变化的状态
}, [/* 只包含稳定的依赖 */]);
```
### 3. **useEffect依赖管理**
```typescript
// ✅ 初始化逻辑使用空依赖数组
useEffect(() => {
// 初始化逻辑
}, []); // 只执行一次
// ✅ 响应式逻辑明确依赖
useEffect(() => {
// 响应某个值的变化
}, [specificValue]);
```
## 📈 性能改进
### 请求优化
-**减少网络请求**:从无限循环到按需请求
-**智能缓存**30分钟缓存机制正常工作
-**内存优化**:避免不必要的重渲染
### 用户体验
-**页面流畅**:消除卡顿问题
-**快速加载**:缓存数据立即可用
-**错误处理**:网络失败时使用缓存
## 🎉 总结
通过重构Hook的依赖关系和执行流程成功修复了无限循环问题
-**移除循环依赖**fetchShopInfo不再依赖shopInfo
-**优化初始化**useEffect只执行一次
-**独立刷新函数**:避免函数间的循环依赖
-**保持功能完整**:所有原有功能正常工作
-**性能提升**:从无限请求到智能缓存
**现在useShopInfo Hook工作正常不再有无限循环问题** 🚀