facebook/react · warning

React Hook useEffect requires an effect callback. Did you fo

Error message

React Hook useEffect requires an effect callback. Did you forget to pass a callback to the hook?

What it means

The exported useEffect checks in dev that its first argument is not null/undefined before forwarding to the dispatcher (ReactHooks.js:93). An effect hook without a callback has nothing to schedule; the warning fires at call time, and if the undefined slips through to commit, React later crashes with 'create is not a function' (TypeError) inside commitHookEffectListMount.

Source

Thrown at packages/react/src/ReactHooks.js:93

  initialArg: I,
  init?: I => S,
): [S, Dispatch<A>] {
  const dispatcher = resolveDispatcher();
  return dispatcher.useReducer(reducer, initialArg, init);
}

export function useRef<T>(initialValue: T): {current: T} {
  const dispatcher = resolveDispatcher();
  return dispatcher.useRef(initialValue);
}

export function useEffect(
  create: () => (() => void) | void,
  deps: Array<mixed> | void | null,
): void {
  if (__DEV__) {
    if (create == null) {
      console.warn(
        'React Hook useEffect requires an effect callback. Did you forget to pass a callback to the hook?',
      );
    }
  }

  const dispatcher = resolveDispatcher();
  return dispatcher.useEffect(create, deps);
}

export function useInsertionEffect(
  create: () => (() => void) | void,
  deps: Array<mixed> | void | null,
): void {
  if (__DEV__) {
    if (create == null) {
      console.warn(
        'React Hook useInsertionEffect requires an effect callback. Did you forget to pass a callback to the hook?',
      );

View on GitHub (pinned to eafeac097b)

Solutions

  1. Always pass the effect function: useEffect(() => {...}, [deps])
  2. Keep the call unconditional and branch inside the callback when the effect is optional
  3. Enable TypeScript/Flow checking and eslint-plugin-react-hooks so a missing argument fails CI, not runtime

Example fix

// before
useEffect(loggedIn ? loadProfile : undefined, [loggedIn]);

// after
useEffect(() => {
  if (loggedIn) loadProfile();
}, [loggedIn]);
Defensive patterns

Strategy: validation

Validate before calling

// dev assert before the hook (keeps the hook call unconditional)
if (__DEV__ && typeof create !== 'function') {
  throw new TypeError('useEffect requires an effect callback');
}
useEffect(create, deps);

Type guard

const isEffectCallback = (x) => typeof x === 'function';

Prevention

When it happens

Trigger: useEffect() called with no arguments; useEffect(undefined, [deps]); passing a conditionally-chosen callback (cond ? fn : undefined); passing a function call's result instead of the function, e.g. useEffect(fn(), deps).

Common situations: 'Optional' effects written conditionally; refactors that rename or delete the callback but leave the hook call; typed-loose JS where the argument silently becomes undefined.

Related errors


AI-assisted analysis of facebook/react@eafeac097b (2026-08-21). Data as JSON: /api/errors/ab05e0afa9db559a. Report an issue: GitHub.