[Solved] Unnecessary re-renders in Scheduler

1 Answer 9 Views
Scheduler
Andrei
Top achievements
Rank 2
Iron
Iron
Andrei asked on 13 Jul 2026, 08:31 AM
I am facing a performance issue with the Scheduler component. I pass a CustomItem into the Scheduler, and inside this CustomItem, I use the standard SchedulerItem from the library. The Scheduler also includes a context menu Popup that opens on a right-click.
When the context menu opens, it updates a useState value inside the Scheduler component. This causes the Scheduler to re-render, which in turn forces all of its child components—including all CustomItem instances—to re-render as well.
To prevent these unnecessary re-renders, I wrapped CustomItem in React.memo (line 32 in the provided example). However, this did not solve the problem. All CustomItem components still re-render, which negatively impacts the application's performance.

I have simplified this example for clarity. In my actual project, I pass more than just onContextMenuOpen into CustomItem, so my question goes beyond just fixing the popup behavior. Is there a way to prevent all CustomItem instances from re-rendering when the parent component updates, given that I use custom items and pass additional props into them?

Thanks!

1 Answer, 1 is accepted

Sort by
0
Vessy
Telerik team
answered on 14 Jul 2026, 03:23 PM

Hello, Andrei,

The behavior observed is expected and stems from how React's `React.memo` works in combination with the Scheduler's internal rendering pipeline.

`React.memo` performs a shallow comparison of props. When the parent component re-renders (e.g., due to a `useState` update for the context menu), the Scheduler's internal components produce new object and function references for the props passed to custom items - such as event handlers (`onClick`, `onFocus`, etc.) and the `style` object. Since these are new references on every render, `React.memo`'s shallow comparison sees them as "changed" and triggers a re-render of the custom item regardless.

To prevent unnecessary re-renders of `CustomItem`, avoid passing values derived from changing state directly as props. You can use `useRef` instead of `useState` for values that don't need to trigger re-renders or to fully benefit from memoization by defining the wrapper component outside the render cycle like in the sample below.

This approach avoids prop drilling entirely and keeps the custom item's props stable:

import * as React from 'react';
import { Scheduler, WeekView } from '@progress/kendo-react-scheduler';
import { SchedulerItem } from '@progress/kendo-react-scheduler';

// 1. Create a context for the context menu handler
const ContextMenuContext = React.createContext<((e: React.MouseEvent, dataItem: any) => void) | null>(null);

// 2. Define CustomItem OUTSIDE the App component — this keeps the reference stable
const CustomItem = (props: any) => {
    const onContextMenuOpen = React.useContext(ContextMenuContext);

    const handleContextMenu = React.useCallback((e: React.MouseEvent) => {
        e.preventDefault();
        onContextMenuOpen?.(e, props.dataItem);
    }, [onContextMenuOpen, props.dataItem]);

    return (
        <div onContextMenu={handleContextMenu}>
            <SchedulerItem {...props} />
        </div>
    );
};

const App = () => {
    const [menuVisible, setMenuVisible] = React.useState(false);
    const contextMenuDataRef = React.useRef<any>(null);

    // Stable callback via useCallback
    const handleContextMenuOpen = React.useCallback((e: React.MouseEvent, dataItem: any) => {
        contextMenuDataRef.current = { x: e.clientX, y: e.clientY, dataItem };
        setMenuVisible(true);
    }, []);

    return (
        <ContextMenuContext.Provider value={handleContextMenuOpen}>
            <Scheduler
                data={[/* ... */]}
                item={CustomItem}
            >
                <WeekView />
            </Scheduler>
            {/* Render your Popup/context menu here using menuVisible and contextMenuDataRef.current */}
        </ContextMenuContext.Provider>
    );
};

I hope the provided information will be helpful for you but let me know if I can assist you any further on this matter.

Regards,
Vessy
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

 

Tags
Scheduler
Asked by
Andrei
Top achievements
Rank 2
Iron
Iron
Answers by
Vessy
Telerik team
Share this question
or