All answers

React Native

What does "Minified React error #321" mean?

It's React's "Invalid hook call" error. A hook ran somewhere other than the top level of a function component, such as inside a FlatList renderItem function or an event handler, or your app has mismatched or duplicate copies of React. Run it in development to find the component, then move the hook or fix the versions.

Updated October 31, 2026

A crash that only says Minified React error #321 gives you a number and a link, which isn’t much to go on. React’s production builds leave out full error messages to send fewer bytes, and #321 is “Invalid hook call. Hooks can only be called inside of the body of a function component.” You’ll see the number in the production web version of your app, because the production builds for iOS and Android keep the full text.

Why it happens

React’s own message lists three reasons:

  1. A hook is called in the wrong place. Hooks like useState and useEffect only work at the top level of a function component or a custom hook, so calling one inside an event handler, a class component, or a function you pass to useEffect or useMemo breaks this rule. One React Native case that’s easy to miss is a hook inside a FlatList renderItem function, which is called from inside the list’s own class component rather than from your component.
  2. React and the renderer don’t match, for example react and react-dom on different versions.
  3. There’s more than one copy of React in the app, for example because a package installed its own.

How to fix it

  1. Get the full message. Run the app in development with npx expo start, open the screen that crashed, and read the error and the component it names. React’s docs recommend the development build for debugging, because it shows full messages and extra warnings.

  2. Move the hook into a component. For a list row, make the row its own component, so each row’s hooks belong to it:

    // Before: a hook inside renderItem
    <FlatList
      data={items}
      renderItem={({ item }) => {
        const [liked, setLiked] = useState(false);
        return <Row item={item} liked={liked} onToggle={() => setLiked(!liked)} />;
      }}
    />;
    
    // After: the row owns its state
    function ItemRow({ item }: { item: Item }) {
      const [liked, setLiked] = useState(false);
      return <Row item={item} liked={liked} onToggle={() => setLiked(!liked)} />;
    }
    
    <FlatList data={items} renderItem={({ item }) => <ItemRow item={item} />} />;

    The same fix works for a hook inside an event handler or an effect, where you call the hook at the top of the component and use its value inside the callback.

  3. Line up your versions. In an Expo project, this checks react, react-dom, react-native, and the Expo packages against your SDK and offers to fix them:

    npx expo install --check
  4. Look for a second copy of React:

    npm why react

    If you see more than one version, the output shows which package brought in the extra copy. Update that package, or add an override so it uses your app’s version.

How you know it’s fixed

In development, the screen opens without an “Invalid hook call” message in the logs. The production web build should load it too.

If it still crashes

If the crash in production reads like Cannot read properties of null (reading 'useState'), look harder at duplicate copies of React. A copy that no renderer is using has no hook dispatcher set, so its hooks fail on a null value instead of with #321. In a monorepo, Expo’s guide notes that duplicate React versions in one app cause runtime errors, so check every workspace with npm why react (or yarn why react). And if a third-party component crashes with #321, we’d check its React requirements against yours before changing your own code.

Ask the agent

If your app is in Draftbit, paste this into the agent, and it can read your code and make the change for you.

My app crashes with Minified React error #321 (invalid hook call). Run it in development to find the component, move any hooks that are called inside callbacks, renderItem functions, or class components into their own function components, and check that we only have one copy of React with versions that match.

Open Draftbit

More React Native answers