streamich/react-use · error · Error
useStateContext must be used inside a StateProvider.
Error message
useStateContext must be used inside a StateProvider.
What it means
Thrown by the hook returned from createStateContext when it is called outside a matching <StateProvider>. The factory creates a context defaulted to undefined; useStateContext reads it with useContext and, when the value is null or undefined (== null), concludes no provider is supplying the [value, setValue] tuple and throws. It is the state (useState) analogue of the reducer-context guard and has the same structural cause.
Source
Thrown at src/factory/createStateContext.ts:22
const context =
createContext<[T, React.Dispatch<React.SetStateAction<T>>] | undefined>(undefined);
const providerFactory = (props, children) => createElement(context.Provider, props, children);
const StateProvider = ({
children,
initialValue,
}: {
children?: React.ReactNode;
initialValue?: T;
}) => {
const state = useState<T>(initialValue !== undefined ? initialValue : defaultInitialValue);
return providerFactory({ value: state }, children);
};
const useStateContext = () => {
const state = useContext(context);
if (state == null) {
throw new Error(`useStateContext must be used inside a StateProvider.`);
}
return state;
};
return [useStateContext, StateProvider, context] as const;
};
export default createStateContext;
View on GitHub (pinned to fbe99c6327)
Solutions
- Wrap the consuming subtree in the <StateProvider> returned from the same createStateContext call.
- Call createStateContext once at module scope, export both useStateContext and StateProvider together, and import them as a pair — never mix members from two factory calls.
- In tests/SSR, mount the consumer inside the provider rather than bare.
- Lift the provider above any portal or Suspense boundary that contains the consumer.
Example fix
// before
const [useStateContext, StateProvider] = createStateContext(0);
function Child() {
const [count, setCount] = useStateContext(); // throws: no provider above
return <p>{count}</p>;
}
export default function App() {
return <Child/>;
}
// after
export default function App() {
return (
<StateProvider>
<Child/>
</StateProvider>
);
} Defensive patterns
Strategy: validation
Validate before calling
// Structural: ensure consumers render inside their <StateProvider>. export const [useStateContext, StateProvider] = createStateContext<T>(defaultValue); // Always compose like this: <StateProvider> <ConsumesState/> </StateProvider>
Type guard
// Narrow a value to the [value, setter] tuple expected from the provider. const isStateTuple = <T>( v: unknown ): v is [T, React.Dispatch<React.SetStateAction<T>>] => Array.isArray(v) && v.length === 2 && typeof v[1] === 'function'; // As with error 0, the practical guard is the provider in the tree, not a // pre-call probe (the hook throws on undefined context).
Try / catch
class ProviderBoundary extends React.Component<
{ children: React.ReactNode; fallback: React.ReactNode },
{ hasError: boolean }
> {
state = { hasError: false };
static getDerivedStateFromError() { return { hasError: true }; }
render() {
return this.state.hasError ? this.props.fallback : this.props.children;
}
}
// <ProviderBoundary fallback={<p>StateProvider missing</p>}><Consumes/></ProviderBoundary> Prevention
- Create the context once at module scope and export useStateContext and StateProvider as a pair.
- Place a single StateProvider above all consumers, including across portals/Suspense.
- Never mix a hook from one createStateContext call with a provider from another.
- In unit/SSR tests, mount consumers inside StateProvider via a shared helper.
When it happens
Trigger: Calling the useStateContext hook (first element of the tuple returned by createStateContext(defaultInitialValue)) in a component that is not a descendant of the corresponding <StateProvider>. Also triggered by using a hook from one createStateContext call inside a provider from a different call (each call creates a distinct context).
Common situations: Missing <StateProvider> wrapper around the consuming component; portal/lazy subtrees that escape the provider; isolated unit/SSR renders mounting the consumer without the provider; exporting the hook and Provider from separate factory calls and mixing them.
Related errors
- useReducerContext must be used inside a ReducerProvider.
- useLocalStorage key may not be falsy
- states expected to be an object or array, got ${typeof state
- State '${state}' is not a valid state (does not exist in sta
- Capacity has to be greater than 1, got '${capacity}'
AI-assisted analysis of streamich/react-use@fbe99c6327 (2026-08-12).
Data as JSON: /api/errors/97e9f40da0d72ca0.
Report an issue: GitHub.