React Medium technical 0 views 2 min read

How would you create a reusable Context?

Peer-reviewed by HireXTech Technical Panel Updated for 2025/2026 hiring Editorial standards
Practise this track
Interviewer Expectations for this Question
01
Core Competency

Assesses fundamental understanding of React conventions, runtime behavior, and memory/performance considerations.

02
Evaluation Criteria

Hiring managers look for precision, avoidance of ambiguous jargon, and ability to explain trade-offs under real production conditions.

Comprehensive Model Answer Verified Solution

A reusable Context bundles the createContext call, its Provider (with local state/logic), and a custom hook to consume it into a single module. This hides the raw Context object from consumers, provides a clear API, and lets you validate that the hook is used within its provider.

     // ThemeContext.js
     import { createContext, useContext, useMemo, useState } from "react";

     const ThemeContext = createContext(undefined);

     export function ThemeProvider({ children }) {
       const [theme, setTheme] = useState("light");

       const toggleTheme = () =>
         setTheme((prev) => (prev === "light" ? "dark" : "light"));

       // Memoize so the value reference is stable across renders
       const value = useMemo(() => ({ theme, toggleTheme }), [theme]);

       return (
         <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>
       );
     }

     // Custom hook consumers use instead of importing ThemeContext directly
     export function useTheme() {
       const context = useContext(ThemeContext);
       if (context === undefined) {
         throw new Error("useTheme must be used within a ThemeProvider");
       }
       return context;
     }
     
     // App.js
     function App() {
       return (
         <ThemeProvider>
           <Toolbar />
         </ThemeProvider>
       );
     }

     function Toolbar() {
       const { theme, toggleTheme } = useTheme();
       return <button onClick={toggleTheme}>Current theme: {theme}</button>;
     }
     

#### Why wrap Context like this?

  1. Encapsulation: Consumers never import or touch the raw Context object, so its internal shape can change without breaking callers.
  2. Guardrails: The custom hook throws a clear error if used outside its provider, instead of silently returning undefined.
  3. Colocation: State, updater functions, and derived values live next to the provider, making the context self-contained and easy to test in isolation.
  4. Composability: Multiple reusable contexts (theme, auth, locale, etc.) can be combined by nesting providers, or composed with a helper that merges them.
  5. Performance-friendly: Memoizing the provider's value (with useMemo) avoids creating a new object on every render, reducing unnecessary consumer re-renders (see [Does React.memo prevent Context consumers from re-rendering?](#does-reactmemo-prevent-context-consumers-from-re-rendering)).

Candidate Response Strategy & Interview Tips

  1. Start with a concise one-sentence summary: Deliver a direct, confident answer first before expanding into nuances.
  2. Demonstrate real-world trade-offs: Discuss where this approach excels and when you would avoid it in production systems.
  3. Discuss complexity & edge cases: Proactively explain time/space complexity or boundary conditions (null values, scale limits).
  4. Prepare for interviewer follow-ups: Technical hiring panels frequently probe deeper into concurrency, backward compatibility, or alternative libraries.
Related Topics & Skills
Spotted an error or have an alternative solution?