- 在项目中引入expo-notifications库,支持本地推送通知功能 - 实现通知权限管理,用户可选择开启或关闭通知 - 新增通知发送、定时通知和重复通知功能 - 更新个人页面,集成通知开关和权限请求逻辑 - 编写推送通知功能实现文档,详细描述功能和使用方法 - 优化心情日历页面,确保数据实时刷新
156 lines
5.0 KiB
Markdown
156 lines
5.0 KiB
Markdown
# 心情日历数据实时刷新修复方案
|
||
|
||
## 问题描述
|
||
|
||
用户编辑或新建心情后,当天的心情数据没有实时更新,必须退出页面或切换日期再切换回来才会生效。
|
||
|
||
## 问题原因
|
||
|
||
1. **本地状态与 Redux 状态不同步**:心情日历页面使用本地状态 `moodRecords` 和 `selectedDateMood` 来管理数据,而不是直接使用 Redux store 中的数据。
|
||
|
||
2. **缺少页面焦点监听**:当用户从编辑页面返回时,没有监听页面焦点变化来刷新数据。
|
||
|
||
3. **数据流不一致**:编辑页面通过 Redux 更新数据,但日历页面没有监听这些变化。
|
||
|
||
## 修复方案
|
||
|
||
### 1. 迁移到 Redux 状态管理
|
||
|
||
**修改文件**: `app/mood/calendar.tsx`
|
||
|
||
#### 移除本地状态
|
||
```typescript
|
||
// 移除这些本地状态
|
||
const [selectedDateMood, setSelectedDateMood] = useState<any>(null);
|
||
const [moodRecords, setMoodRecords] = useState<Record<string, any[]>>({});
|
||
```
|
||
|
||
#### 使用 Redux 状态
|
||
```typescript
|
||
// 使用 Redux store 中的数据
|
||
const moodRecords = useAppSelector(state => state.mood.moodRecords);
|
||
|
||
// 获取选中日期的数据
|
||
const selectedDateString = selectedDay ? dayjs(currentMonth).date(selectedDay).format('YYYY-MM-DD') : null;
|
||
const selectedDateMood = selectedDateString ? useAppSelector(selectLatestMoodRecordByDate(selectedDateString)) : null;
|
||
```
|
||
|
||
### 2. 添加页面焦点监听
|
||
|
||
#### 导入 useFocusEffect
|
||
```typescript
|
||
import { router, useLocalSearchParams, useFocusEffect } from 'expo-router';
|
||
import React, { useEffect, useState, useCallback } from 'react';
|
||
```
|
||
|
||
#### 添加焦点监听器
|
||
```typescript
|
||
// 监听页面焦点变化,当从编辑页面返回时刷新数据
|
||
useFocusEffect(
|
||
useCallback(() => {
|
||
// 当页面获得焦点时,刷新当前月份的数据和选中日期的数据
|
||
const refreshData = async () => {
|
||
if (selectedDay) {
|
||
const selectedDateString = dayjs(currentMonth).date(selectedDay).format('YYYY-MM-DD');
|
||
await loadDailyMoodCheckins(selectedDateString);
|
||
}
|
||
await loadMonthMoodData(currentMonth);
|
||
};
|
||
refreshData();
|
||
}, [currentMonth, selectedDay, loadDailyMoodCheckins, loadMonthMoodData])
|
||
);
|
||
```
|
||
|
||
### 3. 简化数据加载逻辑
|
||
|
||
#### 移除手动状态更新
|
||
```typescript
|
||
// 加载选中日期的心情记录
|
||
const loadDailyMoodCheckins = async (dateString: string) => {
|
||
try {
|
||
await fetchMoodRecords(dateString);
|
||
// 不需要手动设置 selectedDateMood,因为它现在从 Redux store 中获取
|
||
} catch (error) {
|
||
console.error('加载心情记录失败:', error);
|
||
}
|
||
};
|
||
```
|
||
|
||
#### 简化月份数据加载
|
||
```typescript
|
||
// 加载整个月份的心情数据
|
||
const loadMonthMoodData = async (targetMonth: Date) => {
|
||
try {
|
||
const startDate = dayjs(targetMonth).startOf('month').format('YYYY-MM-DD');
|
||
const endDate = dayjs(targetMonth).endOf('month').format('YYYY-MM-DD');
|
||
|
||
const historyData = await fetchMoodHistoryRecords({ startDate, endDate });
|
||
|
||
// 历史记录已经通过 fetchMoodHistoryRecords 自动存储到 Redux store 中
|
||
// 不需要额外的处理
|
||
} catch (error) {
|
||
console.error('加载月份心情数据失败:', error);
|
||
}
|
||
};
|
||
```
|
||
|
||
### 4. 更新心情图标渲染
|
||
|
||
#### 使用 Redux 数据渲染图标
|
||
```typescript
|
||
const renderMoodIcon = (day: number | null, isSelected: boolean) => {
|
||
if (!day) return null;
|
||
|
||
// 检查该日期是否有心情记录 - 现在从 Redux store 中获取
|
||
const dayDateString = dayjs(currentMonth).date(day).format('YYYY-MM-DD');
|
||
const dayRecords = moodRecords[dayDateString] || [];
|
||
const moodRecord = dayRecords.length > 0 ? dayRecords[0] : null;
|
||
|
||
if (moodRecord) {
|
||
const mood = moodOptions.find(m => m.type === moodRecord.moodType);
|
||
return (
|
||
<View style={[styles.moodIconContainer, { backgroundColor: mood?.color }]}>
|
||
<View style={styles.moodIcon}>
|
||
<Text style={styles.moodEmoji}>{mood?.emoji || '😊'}</Text>
|
||
</View>
|
||
</View>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<View style={styles.defaultMoodIcon}>
|
||
<Text style={styles.defaultMoodEmoji}>😊</Text>
|
||
</View>
|
||
);
|
||
};
|
||
```
|
||
|
||
## 修复效果
|
||
|
||
### 修复前
|
||
- 用户编辑心情后,日历页面数据不更新
|
||
- 需要退出页面或切换日期才能看到变化
|
||
- 用户体验不佳
|
||
|
||
### 修复后
|
||
- 用户编辑心情后,日历页面数据立即更新
|
||
- 页面焦点变化时自动刷新数据
|
||
- 数据状态统一管理,避免不一致
|
||
|
||
## 技术要点
|
||
|
||
1. **统一状态管理**:所有心情数据都通过 Redux 管理,确保数据一致性。
|
||
|
||
2. **响应式更新**:使用 `useAppSelector` 监听 Redux 状态变化,自动更新 UI。
|
||
|
||
3. **页面焦点监听**:使用 `useFocusEffect` 监听页面焦点变化,确保从其他页面返回时数据是最新的。
|
||
|
||
4. **异步数据加载**:保持异步数据加载的性能优势,同时确保数据同步。
|
||
|
||
## 相关文件
|
||
|
||
- `app/mood/calendar.tsx` - 心情日历页面
|
||
- `app/mood/edit.tsx` - 心情编辑页面
|
||
- `store/moodSlice.ts` - 心情 Redux slice
|
||
- `hooks/useMoodData.ts` - 心情数据管理 hook
|