Hey folks! 👋

If you've been working with React for a bit, you’ve probably heard people throw around terms like HOC, Render Props, Container-Presenter, or even Compound Components.

Sounds fancy, right? But what do these actually mean—and more importantly—why should you care?

Let’s break down a few common React design patterns, no theory overload, just straight-up use cases and examples you’d see in your day-to-day code.


🧱 1. Container and Presentational Pattern

What it is:

Split components by logic (container) and UI (presentational).

Why:

Keeps things clean. Easy to test, reuse, and manage.

Example:

// Container
function UserContainer() {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetchUser().then(setUser);
  }, []);

  return <UserProfile user={user} />;
}

// Presentational
function UserProfile({ user }) {
  if (!user) return <p>Loading...p>;
  return <div>{user.name}div>;
}

✔️ Logic stays in one place.

✔️ UI stays dumb and pretty.


🌀 2. Higher Order Components (HOC)

What it is:

A function that takes a component and returns a new one with extra powers.

Why:

Great for code reuse (e.g., auth, logging, theming).

Example:

function withLogger(WrappedComponent) {
  return function(props) {
    useEffect(() => {
      console.log('Component loaded!');
    }, []);

    return <WrappedComponent {...props} />;
  };
}

const FancyButtonWithLog = withLogger(FancyButton);

⚠️ Be careful: Too many HOCs = wrapper hell.


🔁 3. Render Props

What it is:

You pass a function as a prop and call it inside the component to render stuff.

Why:

Flexible. Cleaner than HOCs in some cases.

Example:

function MouseTracker({ render }) {
  const [pos, setPos] = useState({ x: 0, y: 0 });

  useEffect(() => {
    const handler = e => setPos({ x: e.clientX, y: e.clientY });
    window.addEventListener('mousemove', handler);
    return () => window.removeEventListener('mousemove', handler);
  }, []);

  return render(pos);
}

// Usage
<MouseTracker render={({ x, y }) => <h1>{x}, {y}h1>} />

🧠 Think of it like passing a component’s brain to another component’s face.


🧩 4. Compound Components

What it is:

Multiple components that work together using React context.

Why:

Great for building reusable UI libraries or dynamic forms.

Example:

function Tabs({ children }) {
  const [active, setActive] = useState(0);
  return (
    <TabContext.Provider value={{ active, setActive }}>
      {children}
    TabContext.Provider>
  );
}

Tabs.Tab = ({ index, children }) => {
  const { active, setActive } = useContext(TabContext);
  return (
    <button onClick={() => setActive(index)} style={{ fontWeight: active === index ? 'bold' : 'normal' }}>
      {children}
    button>
  );
};

Tabs.Panel = ({ index, children }) => {
  const { active } = useContext(TabContext);
  return active === index ? <div>{children}div> : null;
};

Use like:

<Tabs>
  <Tabs.Tab index={0}>HomeTabs.Tab>
  <Tabs.Tab index={1}>ProfileTabs.Tab>

  <Tabs.Panel index={0}>Welcome HomeTabs.Panel>
  <Tabs.Panel index={1}>Your ProfileTabs.Panel>
Tabs>

🚀 Fancy but powerful. Think Lego bricks that click together.


🧠 TL;DR

React design patterns aren’t magic—they’re just better ways to organize your components and logic so your code stays readable and maintainable.

If you’ve made it this far, you’ve already used these patterns at some point—even if you didn’t know their names. 💡

Let me know in the comments which one you use the most—or if there’s one you want me to explain with memes and analogies next time 😄