{"record":{"id":"97e9f40da0d72ca0","repo":"streamich/react-use","slug":"usestatecontext-must-be-used-inside-a-stateprovide","errorCode":null,"errorMessage":"useStateContext must be used inside a StateProvider.","messagePattern":"useStateContext must be used inside a StateProvider\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/factory/createStateContext.ts","lineNumber":22,"sourceCode":"  const context =\n    createContext<[T, React.Dispatch<React.SetStateAction<T>>] | undefined>(undefined);\n  const providerFactory = (props, children) => createElement(context.Provider, props, children);\n\n  const StateProvider = ({\n    children,\n    initialValue,\n  }: {\n    children?: React.ReactNode;\n    initialValue?: T;\n  }) => {\n    const state = useState<T>(initialValue !== undefined ? initialValue : defaultInitialValue);\n    return providerFactory({ value: state }, children);\n  };\n\n  const useStateContext = () => {\n    const state = useContext(context);\n    if (state == null) {\n      throw new Error(`useStateContext must be used inside a StateProvider.`);\n    }\n    return state;\n  };\n\n  return [useStateContext, StateProvider, context] as const;\n};\n\nexport default createStateContext;\n","sourceCodeStart":4,"sourceCodeEnd":31,"githubUrl":"https://github.com/streamich/react-use/blob/fbe99c6327e6af94df03bc8bd6ecc5e3ff04fbcc/src/factory/createStateContext.ts#L4-L31","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nconst [useStateContext, StateProvider] = createStateContext(0);\nfunction Child() {\n  const [count, setCount] = useStateContext(); // throws: no provider above\n  return <p>{count}</p>;\n}\nexport default function App() {\n  return <Child/>;\n}\n\n// after\nexport default function App() {\n  return (\n    <StateProvider>\n      <Child/>\n    </StateProvider>\n  );\n}","handlingStrategy":"validation","validationCode":"// Structural: ensure consumers render inside their <StateProvider>.\nexport const [useStateContext, StateProvider] = createStateContext<T>(defaultValue);\n\n// Always compose like this:\n<StateProvider>\n  <ConsumesState/>\n</StateProvider>","typeGuard":"// Narrow a value to the [value, setter] tuple expected from the provider.\nconst isStateTuple = <T>(\n  v: unknown\n): v is [T, React.Dispatch<React.SetStateAction<T>>] =>\n  Array.isArray(v) && v.length === 2 && typeof v[1] === 'function';\n\n// As with error 0, the practical guard is the provider in the tree, not a\n// pre-call probe (the hook throws on undefined context).","tryCatchPattern":"class ProviderBoundary extends React.Component<\n  { children: React.ReactNode; fallback: React.ReactNode },\n  { hasError: boolean }\n> {\n  state = { hasError: false };\n  static getDerivedStateFromError() { return { hasError: true }; }\n  render() {\n    return this.state.hasError ? this.props.fallback : this.props.children;\n  }\n}\n// <ProviderBoundary fallback={<p>StateProvider missing</p>}><Consumes/></ProviderBoundary>","preventionTips":["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."],"tags":["react","context","hooks","provider","wiring"],"backgroundTag":null,"analyzedSha":"fbe99c6327e6af94df03bc8bd6ecc5e3ff04fbcc","analyzedAt":"2026-08-12T19:24:06.802Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}