Uncontrolled Components You learned controlled components (state… — Full Stack Camp — TG.ME

✍️ Uncontrolled Components

You learned controlled components (state drives the input). Uncontrolled components let the DOM handle the input's value; you just read it via ref.

function UncontrolledForm() {
  const nameRef = useRef();

  const handleSubmit = (e) => {
    e.preventDefault();
    alert(nameRef.current.value); // Read value directly from DOM
  };

  return (
    <form onSubmit={handleSubmit}>
      <input ref={nameRef} defaultValue="Megersa" />
      <button type="submit">Submit</button>
    </form>
  );
}

When to use: Simple forms where you don't need live validation per keystroke. It's less code but less control.

---

Part 4 --- Stability & Tooling

🚨 Error Boundaries --- Catching Crashes

If a component crashes, the whole React app unmounts (blank screen). Error Boundaries catch JavaScript errors in their child tree and display a fallback UI.

Note: Only works in class components (but you can use libraries like react-error-boundary for functions).

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    console.log("Log error to service:", error);
  }

  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong. Please refresh.</h1>;
    }
    return this.props.children;
  }
}

// Usage
<ErrorBoundary>
  <RiskyComponent />
</ErrorBoundary>

Analogy: Error Boundaries are like circuit breakers in your house. Instead of the whole house (app) going dark when one outlet (component) shorts, the breaker just cuts that one circuit.

---

💤 Suspense & Lazy Loading --- Code Splitting

Why load all your JavaScript at once? With React.lazy, you can load components only when they are needed (e.g., the About page only loads when the user clicks "About").

import { lazy, Suspense } from "react";

// This component will be loaded dynamically
const About = lazy(() => import("./pages/About"));

function App() {
  return (
    <div>
      <Suspense fallback={<div>Loading page...</div>}>
        <About />
      </Suspense>
    </div>
  );
}

Analogy: Lazy loading is like a buffet. Instead of putting every dish on your plate at once (initial load), you go back to the buffet table (server) only when you want the dessert (new page).

---

🧰 Legacy Patterns (HOCs & Render Props)

Before hooks existed, we used these patterns. You might see them in older codebases.

Higher-Order Component (HOC): A function that takes a component and returns a new component with extra props.

function withAuth(Component) {
  return function AuthenticatedComponent(props) {
    const [user] = useContext(UserContext);
    if (!user) return <p>Please login</p>;
    return <Component {...props} user={user} />;
  };
}

Render Props: A prop that is a function returning JSX.

<DataFetcher url="/users">
  {(data) => <div>{data.map(...)}</div>}
</DataFetcher>

Pro Tip: Hooks (useContext, useEffect) replace both of these in modern React. Just know what they are when reading legacy code!

---

🛠️ React DevTools & StrictMode

React DevTools (browser extension):

· Inspect component trees (props, state, hooks).
· Profile performance to see which components re-render.
· Highlight updates to track unnecessary renders.

StrictMode (wrapped in main.jsx):
· Runs extra checks in development (e.g., detects unsafe lifecycles, warns about legacy refs).
· Important: It double-invokes effects in dev to help you catch bugs (don't panic, it's just a test!).

<React.StrictMode>
  <App />
</React.StrictMode>
July 5, 2026 102