Skip to content

React Schedule Events

Handle user interactions and integrate the schedule with your application logic.

Callback props use camelCase names (onCreate, onChangeEvent, onDelete, ...) and receive only the event data — the Schedule instance is available via the forwarded ref.

EventDescription
onBeforeCreateBefore events are added. Always called with an array (length ≥ 1). Return false to cancel.
onBeforeCreate?: (events: Event[], e?: MouseEvent) => boolean | void
onCreateFired after events are added. Always called with an array (length ≥ 1). The MouseEvent is forwarded for interactive creates.
onCreate?: (events: Event[], e?: MouseEvent) => void
onBeforeInsertPer-event hook during the drag-to-create gesture. Return a modified event, or false to drop it.
onBeforeInsert?: (event: Event) => Event | boolean | void
onEditionFired after creating an event interactively, and on double-click of an event.
onEdition?: (event: Event) => void
onDblClickFired on double-click of an event.
onDblClick?: (event: Event) => void
onDeleteFired for each event removed via deleteEvents or the Delete key.
onDelete?: (event: Event) => void
onBeforeChangeEventBefore a drag/resize change is applied. Return false to cancel.
onBeforeChangeEvent?: (state: object) => boolean | void
onChangeEventFired after updateEvent applies changes.
onChangeEvent?: (event: Event, oldValue: Partial<Event>, newValue: Partial<Event>) => void
onBeforeChangeBefore updateEvent / deleteEvents / setData. Return false to cancel.
onBeforeChange?: (state: { action: 'updateEvent' | 'deleteEvents' | 'setData', ...rest }) => boolean | void
onChangeFired after updateEvent / deleteEvents / setData and after an interactive create.
onChange?: () => void
onErrorFired on validation errors (invalid range, conflict, disabled slot, ...).
onError?: (message: string) => void

Handle schedule events with callbacks. onCreate always receives an array (length ≥ 1) — no Array.isArray unwrap.

import { useState } from 'react';
import { Schedule } from '@calendarjs/react';

export default function App() {
    const [data] = useState([]);

    return (
        <Schedule
            type="week"
            value="2025-01-15"
            data={data}
            style={{ height: '500px' }}
            onCreate={(events) => events.forEach((ev) => console.log('Created:', ev.title))}
            onChangeEvent={(event) => console.log('Changed:', event)}
            onDelete={(event) => console.log('Deleted:', event.guid)}
            onDblClick={(event) => console.log('Clicked:', event.title)}
        />
    );
}

Wire the schedule's callbacks to React state for a controlled-mode app. Memoize handlers with useCallback so the wrapper's prop diff sees stable references:

import { useCallback, useState } from 'react';
import { Schedule } from '@calendarjs/react';

export default function App() {
    const [events, setEvents] = useState([]);

    const onCreate = useCallback(
        (created) => setEvents((prev) => [...prev, ...created]),
        [],
    );

    const onChangeEvent = useCallback((event, oldValue, newValue) => {
        setEvents((prev) =>
            prev.map((e) => (e.guid === event.guid ? { ...e, ...newValue } : e)),
        );
    }, []);

    const onDelete = useCallback(
        (event) => setEvents((prev) => prev.filter((e) => e.guid !== event.guid)),
        [],
    );

    return (
        <Schedule
            type="week"
            value="2025-01-15"
            data={events}
            onCreate={onCreate}
            onChangeEvent={onChangeEvent}
            onDelete={onDelete}
            style={{ height: 500 }}
        />
    );
}

Return false from any onBefore* callback to cancel the action. Useful for client-side validation before mutation:

import { Schedule } from '@calendarjs/react';

export default function App() {
    const onBeforeCreate = (events) => {
        if (events.some((ev) => ev.start < '08:00')) {
            alert('Cannot create events before 08:00');
            return false; // cancel
        }
    };

    const onBeforeChange = (state) => {
        if (state.action === 'deleteEvents') {
            return confirm('Delete these events?');
        }
    };

    return (
        <Schedule
            type="week"
            data={[]}
            onBeforeCreate={onBeforeCreate}
            onBeforeChange={onBeforeChange}
            style={{ height: 500 }}
        />
    );
}