Zum Hauptinhalt springen

Quick Start with React Scheduler

Hinweis

This tutorial covers the React wrapper included in the Commercial, Enterprise, and Ultimate editions of DHTMLX Scheduler. If you are using the Individual or GPL edition, follow the alternative guide: How to Start with React.

The React Scheduler component is the official wrapper for DHTMLX Scheduler. This guide walks you through creating a small React application and rendering a basic Scheduler using the trial package.

If you're new to React, start with the official React documentation. Check a complete working project that follows this tutorial on GitHub.

Version requirements

  • React 18 or newer

Creating a new React project

To create a React project and go to the project directory, run the following commands:

npm create vite@latest react-scheduler-quick-start -- --template react-ts
cd react-scheduler-quick-start

Installing React Scheduler

Install React Scheduler as described in the React Scheduler installation guide.

In this tutorial we use the evaluation package:

npm install @dhtmlx/trial-react-scheduler

or

yarn add @dhtmlx/trial-react-scheduler

If you already use the Professional package, replace @dhtmlx/trial-react-scheduler with @dhx/react-scheduler in the commands and imports.

Adding demo data

We'll use static data for this example. Create a file named src/demoData.ts:

import type { Event } from '@dhtmlx/trial-react-scheduler';

export const events: Event[] = [
{
id: 1,
classname: 'blue',
start_date: new Date('2025-12-08T02:00:00Z'),
end_date: new Date('2025-12-08T10:20:00Z'),
text: 'Product Strategy Hike',
},
{
id: 2,
classname: 'blue',
start_date: new Date('2025-12-08T12:00:00Z'),
end_date: new Date('2025-12-08T16:00:00Z'),
text: 'Agile Meditation and Release',
},
{
id: 3,
classname: 'violet',
start_date: new Date('2025-12-09T06:00:00Z'),
end_date: new Date('2025-12-09T11:00:00Z'),
text: 'Tranquil Tea Time',
},
// ....
];

Creating a Scheduler component

To add a Scheduler component, create an src/components/Scheduler/Scheduler.tsx file with the following content:

import { useMemo, useRef } from 'react';
import ReactScheduler, {
type ReactSchedulerRef,
type Event,
type SchedulerTemplates,
type SchedulerConfig,
} from '@dhtmlx/trial-react-scheduler';
import '@dhtmlx/trial-react-scheduler/dist/react-scheduler.css';
import './styles.css';

export interface ReactSchedulerProps {
events: Event[];
activeView?: string;
activeDate?: Date;
}

export default function Scheduler({
events,
activeView = 'week',
activeDate = new Date('2025-12-08T00:00:00Z'),
}: ReactSchedulerProps) {
const schedulerRef = useRef<ReactSchedulerRef>(null);

const templates: SchedulerTemplates = useMemo(
() => ({
event_class: (start: Date, end: Date, event: Event) => {
return event.classname || '';
},
}),
[]
);

const config: SchedulerConfig = useMemo(() => {
return {
first_hour: 6,
last_hour: 22,
hour_size_px: 60,
};
}, []);

return (
<ReactScheduler
ref={schedulerRef}
events={events}
view={activeView}
date={activeDate}
templates={templates}
config={config}
data={{
save: (entity: string, action: string, data: Event, id: string | number) => {
console.log(`${entity} - ${action} - ${id}`, data);
},
}}
/>
);
}

Finally, the CSS classes (.violet, .green, .yellow) are applied through the event_class template to customize the visual appearance of the events:

.violet {
--dhx-scheduler-event-background: linear-gradient(180deg, #d071ef 0%, #ee71d5 100%);
}
.green {
--dhx-scheduler-event-background: linear-gradient(180deg, #12d979 0%, #1ecdeb 100%);
}
.yellow {
--dhx-scheduler-event-background: linear-gradient(180deg, #ffb725 0%, #ffbb25 31.25%, #faea27 100%);
}

Rendering Scheduler in the App

To display Scheduler, replace the code of src/App.tsx with the following one:

import './App.css';
import Scheduler from './components/Scheduler/Scheduler';
import { events } from './demoData';

function App() {
return (
<div style={{ width: '100vw', height: '100vh' }}>
<Scheduler events={events} />
</div>
);
}

export default App;

After that, run the app using the command below:

npm run dev

At this point, you have a fully working React + DHTMLX Scheduler application.

This setup represents the minimum configuration needed to:

  • render a Scheduler
  • display events
  • apply a basic scale configuration
  • attach the Scheduler instance via a React ref
  • receive events through the data.save callback

This is the same minimal example used in the GitHub demo project.

From here, you can continue by adding more advanced features:

  • syncing data with React state
  • loading/saving data from your backend
  • adding templates and custom renderers
  • adding filtering
  • replacing the Lightbox with a custom component

The next sections introduce these capabilities one by one.

Using React state as the source of truth

(recommended for most React apps)

In real applications events usually come from the React state. Below is a complete example where Scheduler sends changes back to React via the data.save callback.

import { useState } from 'react';
import ReactScheduler, { Event } from '@dhtmlx/trial-react-scheduler';
import '@dhtmlx/trial-react-scheduler/dist/react-scheduler.css';
import { events as initialEvents } from './demoData';

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

const data = {
save: (entity, action, item, id) => {
if (entity === 'event') {
if (action === 'create') setEvents((prev) => [...prev, item]);
if (action === 'update') setEvents((prev) => prev.map((x) => (x.id === id ? item : x)));
if (action === 'delete') setEvents((prev) => prev.filter((x) => x.id !== id));
}
},
};

return (
<div style={{ height: '100vh', width: '100vw' }}>
<ReactScheduler
events={events}
data={data}
// ...other props
/>
</div>
);
}

Why choose this mode

  • React always sees the same data as the Scheduler UI
  • Works perfectly with Redux / Zustand / Jotai / MobX
  • Easy to sync with backend APIs

Alternative Mode: Scheduler as the source of truth

(useful for very large datasets)

In this mode React does not own events.

<ReactScheduler
data={{
load: '/api/data', // scheduler loads initial events from here
save: '/api/data', // scheduler sends updates back here
}}
/>

When to prefer this mode

  • Tens of thousands of events
  • Frequent user interactions and updates
  • You want minimal React rendering overhead

Using Templates

(return React elements from template functions)

Templates allow customizing almost every part of the scheduler.

import ReactScheduler, { SchedulerTemplates } from '@dhtmlx/trial-react-scheduler';
import { useMemo } from 'react';
import EventTextBox from './components/EventTextBox';

const templates: SchedulerTemplates = useMemo(
() => ({
event_class: (start, end, event) => {
return 'templates-' + event.classname || '';
},
event_text: (start, end, event) => {
return <EventTextBox event={event} />;
},
}),
[]
);

<ReactScheduler templates={templates} />;

More details

See the full section here: React Scheduler Templates Documentation.

GitHub demo repository

A complete working project that follows this tutorial is provided on GitHub.

Next steps

Need help?
Got a question about the documentation? Reach out to our technical support team for help and guidance. For custom component solutions, visit the Services page.