react-usecontext

Use when working with React Context — deciding whether to use it, optimizing context value to prevent re-renders, or implementing compound components. Covers context value memoization, alternatives, and the compound components pattern.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "react-usecontext" with this command: npx skills add b4r7x/agent-skills/b4r7x-agent-skills-react-usecontext

React useContext

Overview

Context provides "global" data to a component tree without prop drilling. The key insight: context is overused the same way Redux once was — consider simpler alternatives first.

When to Use Context

  • Truly global, stable data — auth/user, theme, i18n, permissions
  • Deep prop drilling (3+ levels) — props passing through components that don't use them
  • Compound components — local, isolated context for tightly coupled UI (best use case)

When NOT to Use

ScenarioUse instead
1-2 levels of propsNormal props — it's not "drilling"
Frequently changing stateZustand / Jotai
Server data (fetch, cache)React Query / TanStack Query
Single-branch dataLocal useState
Deep but simple structureComponent composition

Component Composition (often overlooked)

// ❌ Prop drilling through 3 levels
<Layout user={user}>
  <Sidebar user={user}>
    <UserAvatar user={user} />
  </Sidebar>
</Layout>

// ✅ Composition — Layout knows nothing about user
<Layout sidebar={<Sidebar><UserAvatar user={user} /></Sidebar>}>

Key Nuance

Only components that directly call useContext re-render when context value changes. Deeply nested components that don't consume the context are unaffected — don't over-optimize with memo() on components that don't use the context.

Context Value Optimization

Two orthogonal problems require separate solutions:

ProblemSolution
Context consumers re-render on every provider renderuseMemo on value
Children re-render because parent re-rendersmemo() on child component

Full protection pattern

function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  const logout = useCallback(() => setUser(null), []);
  // ✅ Stable value — consumers only re-render when user changes
  const value = useMemo(() => ({ user, logout }), [user, logout]);
  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}

// ✅ memo prevents re-renders from parent, useMemo prevents re-renders from context
const UserAvatar = memo(function UserAvatar() {
  const { user } = useContext(AuthContext);
  return <img src={user.avatar} />;
});

Without memo on children: useMemo on value protects consumers from unnecessary context changes, but children still re-render when the provider's parent re-renders — these are different mechanisms.

Compound Components (Best Context Use Case)

Local, isolated context for tightly coupled UI — no risk of "too many consumers":

const TabsContext = createContext(null);

function useTabs() {
  const ctx = useContext(TabsContext);
  if (!ctx) throw new Error('Tabs.* must be used inside <Tabs>');
  return ctx;
}

function Tabs({ children, defaultTab }) {
  const [activeTab, setActiveTab] = useState(defaultTab);
  const value = useMemo(() => ({ activeTab, setActiveTab }), [activeTab]);
  return (
    <TabsContext.Provider value={value}>
      <div className="tabs">{children}</div>
    </TabsContext.Provider>
  );
}

Tabs.Tab = function Tab({ id, children }) {
  const { activeTab, setActiveTab } = useTabs();
  return (
    <button className={activeTab === id ? 'active' : ''} onClick={() => setActiveTab(id)}>
      {children}
    </button>
  );
};

Tabs.Panel = function TabPanel({ id, children }) {
  const { activeTab } = useTabs();
  if (activeTab !== id) return null;
  return <div className="tab-panel">{children}</div>;
};

Every major component library (Radix UI, Headless UI, React Aria) uses this pattern.

Anti-pattern: Mega-Context

// ❌ One context for everything — any change re-renders ALL consumers
<AppContext.Provider value={{ user, cart, theme, notifications }}>

// ✅ Separate, isolated contexts
<ThemeProvider>
  <AuthProvider>
    <CartProvider>
      {children}
    </CartProvider>
  </AuthProvider>
</ThemeProvider>

References

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

improve-prompt

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

humanize-readme

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

human-commit

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

deep-plan

No summary provided by upstream source.

Repository SourceNeeds Review