React Native日历添加事件后日期变色及FlatList事件留存需求
React Native 日历功能优化需求
- 为添加过事件的特定日期(如2022-12-23)修改日历中的背景色
- 该背景色需持久保留,直到手动重启应用
- 添加新事件时,FlatList需保留原有事件,展示所有未手动删除的事件
相关代码
function Four({ navigation, route }) { const { dateTime } = route.params; const [name, setName] = useState(); const [note, setNote] = useState(); const [des, setDes] = useState(); const [result, setResult] = useState(); return ( <View> <TextInput value={dateTime} /> <Text>{'\n'}</Text> <TextInput placeholder="Enter Event Title" value={name} onChangeText={value => { setResult(value); setName(value); }} /> <Text>{'\n'}</Text> <TextInput placeholder="Enter Note" value={note} onChangeText={value => { setNote(value); setResult(value); }} /> <Text>{'\n'}</Text> <TextInput placeholder="Enter Description" value={des} onChangeText={value => { setDes(value); setResult(value); }} /> <Text>{'\n'}</Text> <Button title="add event" onPress={() => navigation.navigate('three', { paramKey: dateTime, paramKey1: name, paramKey2: note, paramKey3: des }) } /> </View> ); }
当前效果

实现方案
1. 持久化存储事件与日期标记
要实现颜色持久化和事件不丢失,需用本地存储(推荐@react-native-async-storage/async-storage)存储所有事件及带事件的日期列表。
步骤1:安装依赖
npm install @react-native-async-storage/async-storage # 或 yarn add @react-native-async-storage/async-storage
步骤2:修改事件添加逻辑(Four组件)
替换原导航传参逻辑,将事件存入本地存储:
import AsyncStorage from '@react-native-async-storage/async-storage'; function Four({ navigation, route }) { const { dateTime } = route.params; const [name, setName] = useState(''); const [note, setNote] = useState(''); const [des, setDes] = useState(''); const saveEvent = async () => { if (!name) return; const newEvent = { date: dateTime, title: name, note: note, description: des, id: Date.now().toString() // 唯一ID用于删除操作 }; // 读取已有事件并追加新事件 const existingEvents = await AsyncStorage.getItem('calendarEvents'); const eventsList = existingEvents ? JSON.parse(existingEvents) : []; eventsList.push(newEvent); await AsyncStorage.setItem('calendarEvents', JSON.stringify(eventsList)); // 更新带事件的日期集合 const eventDates = await AsyncStorage.getItem('eventDates'); const datesSet = eventDates ? new Set(JSON.parse(eventDates)) : new Set(); datesSet.add(dateTime); await AsyncStorage.setItem('eventDates', JSON.stringify([...datesSet])); // 返回日历页面 navigation.navigate('three'); }; return ( <View style={{ padding: 16 }}> <TextInput value={dateTime} editable={false} style={{ padding: 8, borderWidth: 1, borderRadius: 4 }} /> <Text>{'\n'}</Text> <TextInput placeholder="输入事件标题" value={name} onChangeText={setName} style={{ padding: 8, borderWidth: 1, borderRadius: 4 }} /> <Text>{'\n'}</Text> <TextInput placeholder="输入备注" value={note} onChangeText={setNote} style={{ padding: 8, borderWidth: 1, borderRadius: 4 }} /> <Text>{'\n'}</Text> <TextInput placeholder="输入描述" value={des} onChangeText={setDes} style={{ padding: 8, borderWidth: 1, borderRadius: 4, minHeight: 80 }} multiline /> <Text>{'\n'}</Text> <Button title="添加事件" onPress={saveEvent} /> </View> ); }
2. 日历组件修改日期背景色
在日历页面(three组件)中,读取存储的日期列表,为对应日期设置背景色(以常用的react-native-calendars库为例):
import AsyncStorage from '@react-native-async-storage/async-storage'; import { Calendar } from 'react-native-calendars'; function Three({ navigation }) { const [markedDates, setMarkedDates] = useState({}); const [events, setEvents] = useState([]); // 页面加载/聚焦时读取存储数据 useEffect(() => { loadStoredData(); const focusListener = navigation.addListener('focus', loadStoredData); return () => focusListener(); }, [navigation]); const loadStoredData = async () => { // 加载带事件的日期并转换为日历组件需要的格式 const eventDates = await AsyncStorage.getItem('eventDates'); const dates = eventDates ? JSON.parse(eventDates) : []; const marked = {}; dates.forEach(date => { marked[date] = { selected: true, selectedColor: '#2196F3' }; // 自定义背景色 }); setMarkedDates(marked); // 加载所有事件 const eventsList = await AsyncStorage.getItem('calendarEvents'); setEvents(eventsList ? JSON.parse(eventsList) : []); }; // 删除事件逻辑 const deleteEvent = async (eventId, eventDate) => { let eventsList = await AsyncStorage.getItem('calendarEvents'); eventsList = JSON.parse(eventsList) || []; const updatedEvents = eventsList.filter(item => item.id !== eventId); await AsyncStorage.setItem('calendarEvents', JSON.stringify(updatedEvents)); // 检查该日期是否还有其他事件,无则移除日期标记 const hasOtherEvents = updatedEvents.some(item => item.date === eventDate); if (!hasOtherEvents) { let eventDates = await AsyncStorage.getItem('eventDates'); eventDates = JSON.parse(eventDates) || []; const updatedDates = eventDates.filter(date => date !== eventDate); await AsyncStorage.setItem('eventDates', JSON.stringify(updatedDates)); const updatedMarked = {...markedDates}; delete updatedMarked[eventDate]; setMarkedDates(updatedMarked); } setEvents(updatedEvents); }; return ( <View style={{ flex: 1 }}> <Calendar markedDates={markedDates} // 其他日历配置项 /> {/* 展示所有事件的FlatList */} <FlatList data={events} keyExtractor={item => item.id} renderItem={({ item }) => ( <View style={{ padding: 12, borderBottomWidth: 1, borderColor: '#eee' }}> <Text style={{ fontWeight: 'bold' }}>{item.date} - {item.title}</Text> {item.note && <Text>备注:{item.note}</Text>} {item.description && <Text>描述:{item.description}</Text>} <Button title="删除" onPress={() => deleteEvent(item.id, item.date)} color="#f44336" style={{ marginTop: 8 }} /> </View> )} /> </View> ); }
3. FlatList保留所有事件
通过上述逻辑,添加事件时直接往存储的事件数组中追加新条目,而非覆盖;FlatList直接渲染完整的事件列表,删除时仅移除对应ID的事件,自然实现所有未删除事件的留存展示。
内容的提问来源于stack exchange,提问作者user19534405
相关产品推荐
相关产品推荐

