迁移到新的 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 的自由函数。
  • createCalendarcreateEventcreateReminder 返回类实例,而不是字符串 ID。

安装

安装包含新 expo-calendar API 且与 SDK 兼容的包:

Terminal
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 的一部分 — 它来自事件实例。展示选项(allowsEditingallowsCalendarPreviewstartNewActivityTask)现在作为同一个 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();

useCalendarPermissionsuseRemindersPermissions hooks 保持不变。

破坏性语义变化

  • 日历、事件、提醒和参与者现在都是类实例。操作变成了实例上的方法,而不是接受 ID 的自由函数。如果你只有 ID,请使用相应的 .get(id) 静态方法获取实例。
  • createCalendarcreateEventcreateReminder 返回类实例,而不是字符串 ID。
  • 去掉了 Async 后缀。该库的大多数方法都是异步的——只有同步函数才使用 Sync 后缀(例如,getDefaultCalendarSyncgetSourcesSyncgetOccurrenceSync)。
  • getSourcesAsync 被同步的 getSourcesSync 取代。按 ID 获取单个数据源没有直接对应项。
  • createEventInCalendarAsync 重命名为 calendar.addEventWithForm
  • openEventInCalendar(即一次性执行的同步变体)已被移除。请改用 event.openInCalendar()
  • 参与者操作现在是实例方法:创建参与者通过 ExpoCalendarEvent 实例上的 event.createAttendee() 完成;更新和删除是结果 ExpoCalendarAttendee 实例上的方法。

参考

Calendar

查看 expo-calendar 的完整 API 参考。