The useContext hook is not a function error means that React is trying to call useContext as if it were a function, but it’s not finding it where it expects to. This almost always boils down to a version mismatch or an incorrect import.
Here are the common causes and their fixes:
-
Incorrect React Version:
useContextwas introduced in React 16.3. If you’re using an older version of React, it simply won’t exist.- Diagnosis: Check your
package.jsonfile for thereactandreact-domdependencies. - Fix: Ensure both
reactandreact-domare at version 16.3.0 or higher. For example, update them to the latest stable versions:npm install react@latest react-dom@latest # or yarn add react@latest react-dom@latest - Why it works: This provides the
useContextAPI that React expects.
- Diagnosis: Check your
-
Incorrect Import: You might be importing
useContextfrom the wrong place. It should always be imported directly from thereactpackage.- Diagnosis: Search your codebase for
useContextimports. Look for patterns likeimport { useContext } from 'some-other-library';orimport useContext from 'react';. - Fix: Ensure your imports look like this:
The correct import for the hook is always:import React, { useContext } from 'react'; // or if you are using named exports in your own modules: // import { useContext } from './my-context-provider'; // This is WRONG for the hook itselfimport { useContext } from 'react'; - Why it works: This tells JavaScript to get the
useContextfunction from the official React library, where it’s defined.
- Diagnosis: Search your codebase for
-
Multiple React Versions in Dependencies: Sometimes, even if your top-level
package.jsonspecifies a correct React version, a dependency might be pulling in an older version of React. This can lead to theuseContextfunction being unavailable or the wrong version being used.- Diagnosis: Run
npm ls reactoryarn why reactin your project’s root directory. This will show you where React is being installed from. Look for multiple versions. - Fix: Use
npm dedupeoryarn dedupeto try and resolve version conflicts. If that doesn’t work, you might need to explicitlyresolutionsinpackage.json(for Yarn) oroverrides(for npm) to force a specific version:
Then run// package.json (npm example) "overrides": { "react": "^18.0.0", "react-dom": "^18.0.0" }npm installoryarn install. - Why it works: This ensures that only one, compatible version of React is installed and used throughout your application, preventing conflicting
useContextimplementations.
- Diagnosis: Run
-
Using
useContextin a Class Component: TheuseContexthook is exclusively for functional components. You cannot use it within a class component’s lifecycle methods or render method.- Diagnosis: Review the component where you’re seeing the
useContexterror. If it’s a class component (defined using theclasskeyword), this is the problem. - Fix: Convert the class component to a functional component, or use the
Consumercomponent of your context if you must remain with class components.- Functional Component Conversion:
// Before (Class Component) // import React, { Component, createContext } from 'react'; // const MyContext = createContext(); // class MyComponent extends Component { // render() { // return ( // <MyContext.Consumer> // {value => <div>{value}</div>} // </MyContext.Consumer> // ); // } // } // After (Functional Component) import React, { useContext } from 'react'; const MyContext = React.createContext(); // Or wherever your context is defined function MyComponent() { const value = useContext(MyContext); return <div>{value}</div>; }
- Functional Component Conversion:
- Why it works: Hooks like
useContextare designed to be called at the top level of functional components, leveraging JavaScript closures and React’s internal state management for functional components.
- Diagnosis: Review the component where you’re seeing the
-
Missing Context Provider: While this usually results in a different error (e.g.,
undefinedcontext value), in some complex setups or with custom build tools, it might manifest as auseContextissue if the provider isn’t correctly integrated or if the context object itself is malformed before being passed touseContext.- Diagnosis: Trace the usage of your
Context.Providercomponent. Ensure it wraps the component callinguseContext. - Fix: Make sure you have a
MyContext.Provider value={...}>wrapping the component that callsuseContext(MyContext).// Parent component function App() { return ( <MyContext.Provider value="someValue"> <MyComponent /> </MyContext.Provider> ); } // MyComponent.js import React, { useContext } from 'react'; // Assume MyContext is imported correctly from where it's defined function MyComponent() { const value = useContext(MyContext); // This will now work return <div>{value}</div>; } - Why it works:
useContextrelies on React’s internal context system to find the nearestProviderancestor. Without a provider, there’s no value to return, and in certain edge cases, this can lead to the hook being called in an invalid state.
- Diagnosis: Trace the usage of your
-
Bundler/Transpiler Configuration Issues: Less common, but your build tools (like Webpack, Babel, or Vite) might be misconfigured, preventing
useContextfrom being correctly transpiled or bundled.- Diagnosis: Check your Babel configuration (
.babelrc,babel.config.js) and Webpack configuration (webpack.config.js). Ensure you have presets and plugins that support modern React features (like@babel/preset-react). - Fix: Update your Babel presets to include
@babel/preset-reactand ensure it’s configured to target your React version. For example, in.babelrc:
Run{ "presets": [ "@babel/preset-env", ["@babel/preset-react", { "runtime": "automatic" }] // or "classic" if you prefer ] }npm install @babel/preset-react --save-devif it’s not already installed. - Why it works: The transpiler needs to understand how to convert JSX and modern JavaScript syntax, including hooks, into code that browsers can execute.
- Diagnosis: Check your Babel configuration (
The next error you’ll likely encounter if you’ve fixed the useContext problem but your context is still not being provided correctly is that useContext will return undefined or the default value you might have set, leading to errors when you try to use that undefined value.