A demo of DHTMLX React Scheduler integrated with Redux Toolkit as the client-side store. All event mutations, view state, and Scheduler config (including a read-only toggle) live in a single Redux slice. Includes snapshot-based undo/redo and a Material UI toolbar. Built with React, TypeScript, and Vite.
This demo shows how to wire DHTMLX React Scheduler to a Redux Toolkit store using the modern createSlice pattern. All calendar events, the active view, the current date, and Scheduler configuration (including a read-only mode flag) live in a single schedulerSlice. Every user mutation flows from Scheduler's data.save callback through typed action creators in actions.ts to the slice reducer.
Undo/redo is implemented as snapshot-based history inside the slice: each mutation action records the previous state before applying the change, and UNDO/REDO actions swap the active snapshot. Read-only mode is stored in the Redux config state and passed to Scheduler's configuration prop, so toggling it from the toolbar disables all editing natively without extra guards.
Redux Toolkit's createSlice uses Immer under the hood, so reducers are written as direct mutations that produce immutable updates — the pattern familiar to any team already using RTK.
- Use this demo when your app already has a Redux store and you want to integrate DHTMLX Scheduler into the same store rather than adding a separate state library.
- Use this when your team is more familiar with Redux Toolkit's
createSlicepattern than with Zustand or Jotai. - Use this when you want Redux DevTools for time-travel debugging of Scheduler state changes.
- Use this as a reference for storing both event data and Scheduler
config(including read-only mode) in the same Redux slice.
git clone https://github.com/DHTMLX/react-scheduler-redux-starter
cd react-scheduler-redux-starter
npm install
npm run devOpen http://localhost:5173 in your browser.
Requirements: Node.js 20.19+ (required by Vite 7), npm.
- Create a new event (click-drag on an empty slot) — dispatches
addEventto the slice. - Drag or resize an event — dispatches
updateEvent. - Delete an event — dispatches
deleteEvent. - Click Undo and Redo in the toolbar to step through the snapshot history.
- Toggle Read-only — the Redux
config.readonlyflag updates and Scheduler immediately blocks all editing.
src/
├── components/
│ ├── Scheduler.tsx # Scheduler init + data.save → Redux action dispatch bridge
│ └── Toolbar.tsx # MUI toolbar: views, navigation, undo/redo, read-only toggle
├── redux/
│ ├── schedulerSlice.ts # RTK slice: events, config, view, date, undo/redo history
│ └── actions.ts # Typed action creators for event CRUD and config updates
├── seed/
│ └── data.ts # Initial events, default view, date, and config
└── App.tsx
The slice (schedulerSlice.ts) is the single source of truth. Scheduler.tsx selects events and config from the store and passes them as Scheduler props. When Scheduler fires data.save(...), Scheduler.tsx calls the matching action creator from actions.ts, which dispatches to the slice reducer. The reducer applies the change and pushes the previous state onto the undo stack.
- RTK
createSlicefor Scheduler state — events, view, active date, and Schedulerconfigall live in a single slice. Immer-powered reducers allow writing mutations directly (e.g.state.events.push(event)) while producing immutable updates, keeping reducer code concise. - Separate
actions.tsfor action creators — CRUD action creators are defined inactions.tsrather than directly in the slice export, keeping the slice focused on state shape and reducer logic while giving callers a clean, typed dispatch interface. - Redux-managed
configfor read-only toggle — Scheduler'sconfig.readonlyis stored in Redux state and passed as a prop. Toggling it dispatches a Redux action, which re-renders the Scheduler with editing disabled. No imperative Scheduler API calls needed. - Snapshot-based undo/redo in the slice — each mutation reducer captures the pre-mutation state as a snapshot before applying the change.
UNDOandREDOreducers swap snapshots. History lives entirely inside Redux, making it inspectable and replayable via Redux DevTools. data.saveto dispatch bridge — Scheduler'sdata.save(entity, action, data, id)is the single entry point for all mutations.Scheduler.tsxmaps eachactionstring (add,update,delete) to the corresponding action creator, keeping Scheduler component logic thin.
| Feature | Details |
|---|---|
| Event CRUD | Create, update, and delete events via Redux Toolkit action creators |
| Drag-and-drop | Rescheduling and resize dispatched as updateEvent actions |
| Views | Day, week, and month |
| Custom MUI toolbar | View switcher, Prev/Next/Today navigation, undo/redo, read-only toggle |
| Undo/redo | Snapshot-based, scoped to event and config mutations; navigation excluded |
| Read-only toggle | config.readonly stored in Redux, passed to Scheduler config prop |
| Redux DevTools | Full time-travel debugging of all Scheduler state changes |
| TypeScript | Full type coverage for slice state, action creators, and event data |
| Vite | Fast dev server and production build |
This demo is a starter, not a production-ready application. For production use:
- Add persistence — events are in-memory only; page refresh resets to seed data. Add RTK Query or a
redux-persistsetup to sync the slice with a backend orlocalStorage. - Integrate with an existing Redux store — if your app already has a store, import
schedulerSliceand add it to yourcombineReducerscall. The slice is self-contained and does not assume it is the only slice. - Scope the undo history — the demo records every event and config mutation. In a real app, consider capping the history depth or excluding bulk import operations from the undo stack.
- Use RTK Query for async data — if events are fetched from a backend, RTK Query integrates cleanly with the slice pattern shown here and handles loading and error states.
- Scheduler license — DHTMLX React Scheduler requires a valid commercial license for production use (see License section below).
- DHTMLX React Scheduler product page
- DHTMLX Scheduler product page
- DHTMLX Scheduler documentation
- DHTMLX Scheduler React integration guide
- Redux Toolkit documentation
- DHTMLX blog
- Community forum
- Report an issue
The source code in this repository is released under the MIT License.
Commercial License Required for proprietary or commercial applications. Includes access to PRO features, dedicated technical support, and long-term maintenance. Learn more →
Try before you buy A free evaluation of DHTMLX React Gantt is available — no credit card required. Start your evaluation →