You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 20:30:41