marmelab/react-admin · error · Error
Cannot call an event handler while rendering.
Error message
Cannot call an event handler while rendering.
What it means
useEvent implements the React 'stable event handler' pattern: the returned function reads fn from a ref that is only updated in useLayoutEffect. Calling the returned function during render hits the ref's initial thrower because the effect has not yet stored the real callback.
Source
Thrown at packages/ra-core/src/util/useEvent.ts:18
import * as React from 'react';
import { useCallback } from 'react';
// allow the hook to work in SSR
const useLayoutEffect =
typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
/**
* Alternative to useCallback that doesn't update the callback when dependencies change
*
* @see https://reactjs.org/docs/hooks-faq.html#how-to-read-an-often-changing-value-from-usecallback
* @see https://github.com/facebook/react/issues/14099#issuecomment-440013892
*/
export const useEvent = <Args extends unknown[], Return>(
fn: (...args: Args) => Return
): ((...args: Args) => Return) => {
const ref = React.useRef<(...args: Args) => Return>(() => {
throw new Error('Cannot call an event handler while rendering.');
});
useLayoutEffect(() => {
ref.current = fn;
});
return useCallback((...args: Args) => ref.current(...args), []);
};
View on GitHub (pinned to 051f511bb0)
Solutions
- Only call the handler from event handlers, effects, timers, or promises — never during render.
- For first-render invocation, wrap the call in useEffect.
- To derive render-time values, call the underlying fn directly rather than the useEvent wrapper.
Example fix
// before
const handler = useEvent(fn);
const value = handler(input); // render-time call -> throws
// after
const handler = useEvent(fn);
React.useEffect(() => { handler(input); }, [input]); Defensive patterns
Strategy: validation
Validate before calling
// Call the useEvent-wrapped handler only from handlers/effects:
React.useEffect(() => {
const id = setTimeout(handler, 0);
return () => clearTimeout(id);
}, []); Try / catch
try {
handler(input);
} catch (e) {
if (e instanceof Error && e.message === 'Cannot call an event handler while rendering.') {
// reroute the call to an effect or event handler
}
} Prevention
- Never call useEvent results during render or in useMemo.
- Compute render-time values from the raw function, not the wrapped handler.
- Keep side-effectful invocations inside useEffect or event handlers.
When it happens
Trigger: Invoking the function returned by useEvent during the render phase of any component — e.g. calling it directly in JSX evaluation, in a render-body statement, or inside useMemo during first render before the layout effect runs.
Common situations: Calling a hook-stabilized handler to compute a value in render, wiring it into a library that calls callbacks synchronously during render, or misunderstanding that the handler is event/effect-time only.
Related errors
- Cannot call an event handler while rendering.
- useTranslatableContext must be used inside a TranslatableCon
- useCloseNotification must be used within a CloseNotification
- usePreference cannot be used outside of a Configurable compo
- usePreferencesEditor must be used within a PreferencesEditor
AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30).
Data as JSON: /api/errors/0bd9d6be066cbd26.
Report an issue: GitHub.