迁移到新的 expo-calendar API
编辑页面
使用 ExpoCalendar、ExpoCalendarEvent 和 hooks,从旧版 expo-calendar API 迁移到新的基于类的 expo-calendar API。
For the complete documentation index, see llms.txt. Use this file to discover all available pages.
The new object-oriented expo-calendar API is now stable. The legacy API is available from expo-calendar/legacy. Migrate to the root expo-calendar import to benefit from the new API and future fixes.
新 API 用类实例上的方法取代了接受 ID 的自由函数。日历、事件、提醒和参与者现在都以各自具有方法的类实例形式表示。主要变化如下:
- 对日历、事件、提醒和参与者的操作现在是对应实例上的方法,而不是接受 ID 的自由函数。
createCalendar、createEvent和createReminder返回类实例,而不是字符串 ID。
安装
安装包含新 expo-calendar API 且与 SDK 兼容的包:
- npx expo install expo-calendar导入新 API
在迁移期间,从 expo-calendar/legacy 导入旧 API,并从 expo-calendar 导入新 API:
// 之前 import * as Calendar from 'expo-calendar/legacy'; // 之后 import { ExpoCalendar, ExpoCalendarEvent } from 'expo-calendar';
日历
创建日历
// 之前 const calendarId = await Calendar.createCalendarAsync({ title: '我的日历', color: '#ff0000' }); // 之后 const calendar = await createCalendar({ title: '我的日历', color: '#ff0000' });
createCalendar 返回的是 ExpoCalendar 实例,而不只是一个 ID。
列出日历
// 之前 const calendars = await Calendar.getCalendarsAsync(Calendar.EntityTypes.EVENT); // 之后 const calendars = await getCalendars(EntityTypes.EVENT);
通过 ID 获取日历
// 之前 // 没有直接对应的方法,必须先从 getCalendarsAsync 结果中过滤 // 之后 const calendar = await ExpoCalendar.get(calendarId);
更新日历
// 之前 await Calendar.updateCalendarAsync(calendarId, { title: '已重命名' }); // 之后 await calendar.update({ title: '已重命名' });
删除日历
// 之前 await Calendar.deleteCalendarAsync(calendarId); // 之后 await calendar.delete();
获取默认日历(仅 iOS)
// 之前 const calendar = await Calendar.getDefaultCalendarAsync(); // 之后 const calendar = getDefaultCalendarSync();
显示日历选择器(仅 iOS)
// 之前 // 没有对应方法 // 之后 const calendar = await presentPicker(); if (calendar) { // 用户选择了一个日历 }
如果应用用户在未选择日历的情况下关闭选择器,presentPicker 会返回 null。
事件
创建事件
// 之前 const eventId = await Calendar.createEventAsync(calendarId, { title: '午餐', startDate, endDate, }); // 之后 const event = await calendar.createEvent({ title: '午餐', startDate, endDate });
createEvent 返回的是 ExpoCalendarEvent 实例,而不只是一个 ID。
列出某个日历中的事件
// 之前 const events = await Calendar.getEventsAsync([calendarId], startDate, endDate); // 之后 const events = await calendar.listEvents(startDate, endDate);
列出多个日历中的事件
// 之前 const events = await Calendar.getEventsAsync([id1, id2], startDate, endDate); // 之后 const events = await listEvents([calendar1, calendar2], startDate, endDate);
通过 ID 获取事件
// 之前 const event = await Calendar.getEventAsync(eventId); // 之后 const event = await ExpoCalendarEvent.get(eventId);
更新事件
// 之前 await Calendar.updateEventAsync(eventId, { title: '与 Alex 共进午餐' }); // 之后 await event.update({ title: '与 Alex 共进午餐' });
旧版 updateEventAsync 接受 recurringEventOptions(仅 iOS)来定位重复事件的单次出现或未来出现项。新 API 不支持这一点 — update() 始终会修改整个重复事件系列。
删除事件
// 之前 await Calendar.deleteEventAsync(eventId); // 之后 await event.delete();
旧版 deleteEventAsync 接受 recurringEventOptions(仅 iOS)来定位重复事件的单次出现或未来出现项。新 API 不支持这一点 — delete() 始终会删除整个重复事件系列。
在日历中打开事件
// 之前 await Calendar.openEventInCalendarAsync(params); // 之后 await event.openInCalendar(params);
id 字段不再是 params 的一部分 — 它来自事件实例。展示选项(allowsEditing、allowsCalendarPreview、startNewActivityTask)现在作为同一个 params 对象传入,而不再作为单独参数。
使用原生日历表单编辑事件
// 之前 await Calendar.editEventInCalendarAsync(params); // 或者,使用表单创建新事件 await Calendar.createEventInCalendarAsync({ title, startDate, endDate }); // 之后 await event.editInCalendar(params); // 或者,使用表单创建新事件 await calendar.addEventWithForm({ title, startDate, endDate });
id 字段不再是 params 的一部分 — 它来自事件实例。展示选项(startNewActivityTask)现在作为同一个 params 对象传入,而不再作为单独参数。
获取重复事件的某个出现项
// 之前 const event = await Calendar.getEventAsync(eventId, { instanceStartDate }); // 之后 const event = await ExpoCalendarEvent.get(eventId); const occurrence = event.getOccurrenceSync({ instanceStartDate });
参与者
获取某个事件的参与者
// 之前 const attendees = await Calendar.getAttendeesForEventAsync(eventId); // 之后 const attendees = await event.getAttendees();
添加参与者
// 之前 const attendeeId = await Calendar.createAttendeeAsync(eventId, { email: 'alex@example.com', name: 'Alex', role: Calendar.AttendeeRole.ATTENDEE, type: Calendar.AttendeeType.PERSON, status: Calendar.AttendeeStatus.ACCEPTED, }); // 之后 const attendee = await event.createAttendee({ email: 'alex@example.com', name: 'Alex' });
更新参与者(仅 Android)
// 之前 await Calendar.updateAttendeeAsync(attendeeId, { name: 'Alexander' }); // 之后 await attendee.update({ name: 'Alexander' });
删除参与者(仅 Android)
// 之前 await Calendar.deleteAttendeeAsync(attendeeId); // 之后 await attendee.delete();
提醒事项(仅 iOS)
创建提醒事项
// 之前 const reminderId = await Calendar.createReminderAsync(calendarId, { title: '买牛奶' }); // 之后 const reminder = await calendar.createReminder({ title: '买牛奶' });
createReminder 返回的是 ExpoCalendarReminder 实例,而不只是一个 ID。
列出提醒事项
// 之前 const reminders = await Calendar.getRemindersAsync([calendarId], status, startDate, endDate); // 之后 const reminders = await calendar.listReminders(startDate, endDate, status);
通过 ID 获取提醒事项
// 之前 const reminder = await Calendar.getReminderAsync(reminderId); // 之后 const reminder = await ExpoCalendarReminder.get(reminderId);
更新提醒事项
// 之前 await Calendar.updateReminderAsync(reminderId, { title: '买燕麦奶' }); // 之后 await reminder.update({ title: '买燕麦奶' });
删除提醒事项
// 之前 await Calendar.deleteReminderAsync(reminderId); // 之后 await reminder.delete();
数据源
// 之前 const sources = await Calendar.getSourcesAsync(); // 之后 const sources = getSourcesSync();
getSourcesAsync 已被同步的 getSourcesSync 替代。通过 ID 获取单个数据源在新 API 中没有直接对应方法。
权限
// 之前 await Calendar.requestCalendarPermissionsAsync(); await Calendar.getCalendarPermissionsAsync(); await Calendar.requestRemindersPermissionsAsync(); await Calendar.getRemindersPermissionsAsync(); // 之后 await requestCalendarPermissions(); await getCalendarPermissions(); await requestRemindersPermissions(); await getRemindersPermissions();
useCalendarPermissions 和 useRemindersPermissions hooks 保持不变。
破坏性语义变化
- 日历、事件、提醒和参与者现在都是类实例。操作变成了实例上的方法,而不是接受 ID 的自由函数。如果你只有 ID,请使用相应的
.get(id)静态方法获取实例。 createCalendar、createEvent和createReminder返回类实例,而不是字符串 ID。- 去掉了
Async后缀。该库的大多数方法都是异步的——只有同步函数才使用Sync后缀(例如,getDefaultCalendarSync、getSourcesSync、getOccurrenceSync)。 getSourcesAsync被同步的getSourcesSync取代。按 ID 获取单个数据源没有直接对应项。createEventInCalendarAsync重命名为calendar.addEventWithForm。openEventInCalendar(即一次性执行的同步变体)已被移除。请改用event.openInCalendar()。- 参与者操作现在是实例方法:创建参与者通过
ExpoCalendarEvent实例上的event.createAttendee()完成;更新和删除是结果ExpoCalendarAttendee实例上的方法。
参考
查看 expo-calendar 的完整 API 参考。