Ojasa Mirai

Ojasa Mirai

ReactJS

Loading...

Learning Level

🟢 Beginner🔵 Advanced
🌍 Context API Basics📦 Creating Context🔌 Context.Provider🔍 useContext Hook🎯 Passing Data with Context🔄 Context with useState⚡ Context Performance🏗️ Context Best Practices
Reactjs/Context/Context Performance

⚡ Context Performance — Avoiding Unnecessary Re-renders

Context is powerful, but every time the value changes, all components using that Context re-render. Understanding this helps you use Context wisely.


🎯 How Context Re-renders Work

When Context value changes, every component that calls `useContext()` for that Context re-renders:

import { createContext, useContext, useState } from "react";

const CounterContext = createContext({ count: 0 });

function App() {
  const [count, setCount] = useState(0);

  // Value changes every render because of {...}
  const value = { count };

  return (
    <CounterContext.Provider value={value}>
      <Counter />
      <ExpensiveComponent />
    </CounterContext.Provider>
  );
}

function Counter() {
  const { count } = useContext(CounterContext);
  return <h1>{count}</h1>; // Re-renders when count changes ✅
}

function ExpensiveComponent() {
  // This component doesn't use Counter, but it re-renders anyway
  return <VeryExpensiveCalculation />;
}

Every time count changes, both Counter and ExpensiveComponent re-render, even though ExpensiveComponent doesn't need the count.

💡 When Context Causes Performance Issues

Context re-renders are problematic when:

1. The value changes frequently (like every keystroke)

2. Many components are listening to that Context

3. Components don't actually use the changed data

// ❌ Bad: Value is a new object every render
function BadApp() {
  const [theme, setTheme] = useState("light");
  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      <Content />
    </ThemeContext.Provider>
  );
  // Every render creates new {theme, setTheme}, causing re-renders
}

// ✅ Good: Value only changes when state changes
function GoodApp() {
  const [theme, setTheme] = useState("light");
  const value = { theme, setTheme };
  return (
    <ThemeContext.Provider value={value}>
      <Content />
    </ThemeContext.Provider>
  );
}

Actually, the good example still has the same problem. Use `useMemo`:

import { useMemo } from "react";

function BestApp() {
  const [theme, setTheme] = useState("light");

  // Value only changes when theme changes
  const value = useMemo(() => ({ theme, setTheme }), [theme]);

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

<details>

<summary>📚 More Examples</summary>

// Example 1: Recognizing performance problems
function App() {
  const [count, setCount] = useState(0);
  const [name, setName] = useState("");

  // ❌ Problem: Both count and name in same Context
  // Changing count causes all useContext(DataContext) to re-render
  // even if they only need name
  return (
    <DataContext.Provider value={{ count, name }}>
      <NameDisplay /> {/* Re-renders on every count change */}
      <CountDisplay /> {/* Re-renders on every count change */}
    </DataContext.Provider>
  );
}

// Example 2: Solution - split into separate contexts
function BetterApp() {
  const [count, setCount] = useState(0);
  const [name, setName] = useState("");

  // ✅ Separate contexts allow independent re-renders
  return (
    <CountContext.Provider value={count}>
      <NameContext.Provider value={name}>
        <NameDisplay /> {/* Only re-renders on name change */}
        <CountDisplay /> {/* Only re-renders on count change */}
      </NameContext.Provider>
    </CountContext.Provider>
  );
}

</details>

🎨 Real-World Example: When to Use Context

Context is great for:

  • App theme (changes rarely)
  • Current language (changes rarely)
  • User authentication (changes rarely)

Context is NOT great for:

  • Form input value (changes on every keystroke)
  • Search results (changes frequently as user types)
  • Real-time data (changes constantly)
// ✅ GOOD: Theme context - changes rarely
const ThemeContext = createContext("light");

function App() {
  const [theme, setTheme] = useState("light");
  return (
    <ThemeContext.Provider value={theme}>
      <Header />
      <Content />
    </ThemeContext.Provider>
  );
}

// ❌ AVOID: Form input context - changes on every keystroke
const InputContext = createContext("");

function FormWithContextProblem() {
  const [input, setInput] = useState("");
  return (
    <InputContext.Provider value={input}>
      {/* This causes re-render on EVERY keystroke! */}
      <Input />
      <ExpensivePreview />
    </InputContext.Provider>
  );
}

// ✅ BETTER: Use useState directly in form component
function FormWithState() {
  const [input, setInput] = useState("");
  return (
    <>
      <input value={input} onChange={(e) => setInput(e.target.value)} />
      <Preview value={input} />
    </>
  );
}

📊 Context Usage Guide

DataChangesBest Approach
ThemeRarelyContext ✅
LanguageRarelyContext ✅
User infoRarelyContext ✅
Form inputFrequentlyuseState ✅
Search queryFrequentlyuseState ✅
FiltersOccasionallyuseState + optional Context

🔑 Key Takeaways

  • ✅ Context re-renders all consumers when value changes
  • ✅ Avoid putting frequently-changing data in Context
  • ✅ Use Context for app-wide data that rarely changes
  • ✅ Split related data into separate Contexts if they change at different rates
  • ✅ Use `useMemo` to prevent unnecessary Provider re-renders
  • ✅ Keep form state local, not in Context
  • ✅ Context works best for configuration data, not dynamic data

Ready to practice? Challenges | Next: Context Best Practices


Resources

Python Docs

Ojasa Mirai

Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.

Learn Deep • Build Real • Verify Skills • Launch Forward

Courses

PythonFastapiReactJSCloud

© 2026 Ojasa Mirai. All rights reserved.

TwitterGitHubLinkedIn