React Components 101: Functions That Build UIs
When I first started using React, I treated components like they were little apps. Overengineered, bloated, and trying to do way too much. I was nesting logic like a Matryoshka doll and wondering why everything felt brittle. Turns out, components in React are supposed to be tiny, focused machines, not sprawling universes. Once that clicked, my code got cleaner, and my frustration dropped significantly. Let’s talk about how to think in components, write them cleanly, and avoid creating mini Frankensteins.
Components: Tiny UI Machines
A React component is basically a function with UI superpowers. It takes in some data (called props), does its little dance, and returns what should appear on screen. Simple in theory. Elegant in practice—when done right.
Think of them like LEGO bricks. You don’t glue them together permanently. You build, snap, replace, reconfigure. That’s the React way. One component = one job.
And if you're wondering how React magically knows what to update and when, spoiler: it’s all thanks to the virtual DOM, which we talked about earlier in the course. React’s engine just needs your components to stay pure and predictable.
Anatomy of a Component (Aka What’s Under the Hood)
Here’s what every basic component has:
A function (or class, but we’re not doing that here—this is 2025) Props as parameters * A return statement with JSX (we’ll dig into JSX more in the next lesson)
function Button({ label }) {
return <button>{label}</button>;
}
That’s it. No decorators. No class hierarchies. No magic. If you’ve ever written a function in JavaScript, you’re halfway to writing a React component.
Props Are Just Arguments (Don’t Overthink It)
Props sound scary until you realize they’re just function arguments with a PR name. React devs love branding, apparently.
Seriously though, passing props is just like calling a function with parameters:
<Button label="Click me" />
The label
prop? Just data passed into the component. Nothing weird going on. I used to obsess over whether I needed to destructure props or access them as props.label
. Turns out: do whatever’s readable.
Here’s the golden rule—components don’t own their data. Props flow down. Think of them as the delivery service of your UI. They carry stuff from parent to child. One-way street. Zero confusion (mostly).
Why Your Button Component Shouldn’t Do Everything
Ah, the classic mistake: writing a Button
component that handles clicks, shows a spinner, conditionally renders icons, logs analytics, and fetches data. I’ve been there. It’s seductive. “Just one more feature…”
But here’s the thing—that’s not a button anymore. That’s an entire app wearing a button costume.
Good React components follow the single-responsibility principle. One component = one purpose. Let your Button
display stuff and forward the onClick
. That’s it. If it needs to do more, wrap it in a container or higher-level component.
This isn’t just opinion. It’s how you keep your code testable, readable, and composable. And it’s how senior devs can smell junior code—from a mile away.
(And yeah, I’ve written button components with if statements inside if statements. Learn from my shame.)
Next up, we’re going to talk about JSX. It looks like HTML... until it doesn’t. It’s time to dive into **JSX: Looks Like HTML, Bites Like JavaScript**. Bring a helmet.