Invalid hook call, explained and fixed

The full message reads “Invalid hook call. Hooks can only be called inside of the body of a function component.” React lists three possible reasons and all three genuinely occur: the rules of hooks were broken in the component, the React and ReactDOM versions do not match, or, the sneakiest, the application is running two copies of React at once, and the component is calling hooks on a different copy than the renderer is using. The fix depends on which of the three it is, and they are easy to tell apart.

Tell the three apart

  1. If it fails in one component and others using hooks work, it is the rules of hooks: the hook is called in a class component, a plain function, a callback, a condition, a loop, or after an early return in that component.
  2. If every hook in the app fails after a dependency change, suspect duplicate React: check the installed tree (npm ls react) and look for two versions, common in monorepos, linked packages (npm link), and libraries that bundle their own React.
  3. If it fails after an upgrade or a partial install, compare versions: react and react-dom must be the same version, and a library's peer React must match the app's copy.

The fixes, matched to the cause

  1. Rules of hooks: call hooks only at the top level of function components or custom hooks, unconditionally, in the same order every render. Move the hook out of the condition or callback, or split the component so the hook owns a component of its own.
  2. Duplicate React: make the library use the app's copy, mark React as a peer dependency in the library, remove nested node_modules/react, and in monorepos hoist or alias so exactly one React resolves. Verify with npm ls react showing a single version.
  3. Version mismatch: align react and react-dom to the identical version and reinstall cleanly; a stale lockfile or a half-applied upgrade is the usual origin.

Common questions

Why does it happen only when I use my own component library? The library is the classic duplicate-React source: it was installed or linked with its own copy of React in its node_modules, so its components talk to one React while the app's renderer talks to another. Peer dependencies plus dedupe at install time is the standard cure.

Can hooks be called in a custom hook? Yes, custom hooks are the second legal place, provided the custom hook itself is called unconditionally at the top level of a component or another custom hook.

The error appeared after adding a hook to a working component, why? If the hook was added inside a condition, after an early return, or in an event handler, renders now disagree about hook order or the call happens outside rendering entirely. Keep hooks above any return and outside any branch.

Related errors

Maximum update depth exceeded · Objects are not valid as a React child · Text content does not match server-rendered HTML