Week 9 Day 4 --- Advanced React: Context, Performance & Real-World… — Full Stack Camp — TG.ME

🌟 Week 9 Day 4 --- Advanced React: Context, Performance & Real-World Patterns

Hello campers 💙

Today we’ll tackle the challenges every large app faces:

· Global state (without drilling props through 10 levels)
· Advanced state logic (like a spreadsheet for your data)
· Custom reusable logic (your own hooks)
· Performance (stop wasted re-renders)
· Portal modals, Error Boundaries, Lazy Loading, and more.

Let’s dive in!


Part 1 --- State Management Deep Dive

⚠️ The Prop Drilling Problem

Remember lifting state up? It works, but what if your component tree is 5 levels deep?

<App>
  <Layout>
    <Sidebar>
      <UserMenu>
        <Avatar user={user} /> {/* user had to travel all the way down */}
      </UserMenu>
    </Sidebar>
  </Layout>
</App>


Passing user through components that don’t even use it is called prop drilling. It’s messy and hard to refactor.

Analogy: Like giving a message to a receptionist, who gives it to a manager, who gives it to a team lead, just to reach the developer. Waste of time.

🧠 Context API --- The Solution

Context provides a way to share data across the entire component tree without passing props manually.

Steps to Use Context

1. Create the Context

import { createContext, useContext } from "react";

const UserContext = createContext();


2. Provide the Context (wrap your parent)

function App() {
  const [user, setUser] = useState({ name: "Megersa" });

  return (
    <UserContext.Provider value={{ user, setUser }}>
      <Dashboard />
    </UserContext.Provider>
  );
}


3. Consume the Context (in any child)

function Avatar() {
  const { user } = useContext(UserContext);
  return <h1>{user.name}</h1>;
}


No more drilling! 🎉

Analogy: Context is like a company-wide announcement system. Instead of whispering down the hallway (props), you broadcast it to everyone who cares (useContext).


⚙️ useReducer --- Complex State Logic

useState is great for simple data (strings, numbers). But when you have complex state with multiple sub-values or transitions (e.g., "ADD_ITEM", "REMOVE_ITEM", "UPDATE_TOTAL"), useReducer is your friend.

Basic Syntax

import { useReducer } from "react";

// 1. Define a reducer function
function cartReducer(state, action) {
  switch (action.type) {
    case "ADD":
      return { ...state, count: state.count + 1 };
    case "REMOVE":
      return { ...state, count: state.count - 1 };
    default:
      return state;
  }
}

function Cart() {
  // 2. useReducer returns [state, dispatch]
  const [state, dispatch] = useReducer(cartReducer, { count: 0 });

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: "ADD" })}>+</button>
      <button onClick={() => dispatch({ type: "REMOVE" })}>-</button>
    </div>
  );
}


Analogy: useState is a light switch (on/off). useReducer is a TV remote—lots of buttons (actions) that change the screen (state) in predictable ways.


🛠️ Custom Hooks --- Reusable Logic

If you find yourself repeating logic across components (e.g., fetching data, tracking window size, managing local storage), extract it into a Custom Hook.

Rules:

· Must start with use (e.g., useFetch).
· Can use other hooks inside (useState, useEffect, useContext).

Example: useFetch


import { useState, useEffect } from "react";

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetch(url)
      .then(res => res.json())
      .then(data => { setData(data); setLoading(false); })
      .catch(err => { setError(err); setLoading(false); });
  }, [url]);

  return { data, loading, error };
}
// Usage in any component
function Users() {
  const { data, loading, error } = useFetch("https://api.example.com/users");
  if (loading) return <p>Loading...</p>;
  return <div>{data.map(user => <p key={user.id}>{user.name}</p>)}</div>;
}
July 5, 2026 84