react-doctor/jsx-no-constructed-context-values

Memoize the context value with useMemo/useCallback or hoist it outside the render

Validation prompt

Use this to decide whether a fired diagnostic is real or a false positive.

Fires on a <X.Provider value={…}> opening element sitting inside a function (a render) when the value expression is constructed fresh each render: an object, array, arrow/function/class expression, new expression, JSX element/fragment, or a conditional/logical whose branches resolve to any of those. Every such provider re-renders all consumers on each parent render because the value gets a new identity. False positive boundary: it only inspects literal construction at the JSX site — an identifier (value={foo}) is never flagged even when foo is an inline {} or an unmemoized useMemo(() => …) with no deps, and spread props (<X.Provider {...rest}>) and member accesses (value={ctx.current}) are likewise not checked, so a confirmed finding is one where the literal sits directly in the attribute.

Fix prompt

Use this once validation confirms the diagnostic is real.

Wrap the value in useMemo (objects/arrays) or useCallback (functions) keyed on its real dependencies: const value = useMemo(() => ({ user, theme }), [user, theme]); return <Ctx.Provider value={value}>. If the value never depends on render state, hoist it to a module-level constant instead. Avoid passing inline {}/[]/arrow functions directly to value, since each render creates a new identity and re-renders every consumer. See https://oxc.rs/docs/guide/usage/linter/rules/react/jsx-no-constructed-context-values