My day started with mango oatmeal, a gecko on the wall, and a Slack ping from Valentina—our newest junior dev in Bogotá.
“Why won’t my button render? I copied the tutorial exactly!”
I glanced at her repo while the sun crawled over the Indian Ocean. One missing import and an outdated ReactDOM.render
was holding her back. Twenty minutes (and one screen-share) later, she yelled “¡Funciona!”—it works. That sunrise session reminded me how magical a first React component feels, especially under React 18. Today, we’ll recreate that moment together—no geckos required.
Why “Hello Component” Still Matters in 2025
Modern build tools, server components, and AI pair-programmers can make learning feel like jumping onto a moving bullet train. Yet every enterprise app—yes, even trillion-row dashboards—starts with one render call. Understanding that single-component lifecycle prevents future migraines when you tackle streaming SSR or concurrent hydration.
Industry pain points I see mentoring boot-camp grads:
Pain Point | Why It Hurts | React 18 Remedy |
---|---|---|
Legacy tutorials stuck on React 16/17 | Newcomers copy obsolete APIs | createRoot() gives instant React 18 parity |
“It works on my laptop” config drift | Inconsistent dev envs across time zones | npx create-vite@latest zero-config starter |
Slow first interaction | Core Web Vitals penalties | Automatic batching & concurrent rendering |
Mastering a humble Button.jsx
today means shipping snappy, accessible features tomorrow.
Concept Check — What Is a React Component?
A React 18 component is a JavaScript function (or class) that returns JSX—a declarative description of UI.
Think of JSX as HTML with superpowers: you can embed variables, conditionals, and even other components.
Under the hood, React converts JSX into lightweight objects (“virtual DOM”) and reconciles them with the real DOM efficiently.
Plain English: A component is a recipe. React 18 is the chef who cooks the minimal changes needed when ingredients (state/props) change.
Step-by-Step: Building & Mounting Your First Component
1 — Project Bootstrap
CLI
npm create vite@latest my-first-react18 -- --template react
cd my-first-react18
npm install
npm run dev
Vite ships with React 18 and the @vitejs/plugin-react-swc
compiler—fast enough to feel instant on hotel Wi-Fi.
2 — Replace Boilerplate
Create src/components/HelloButton.jsx
:
HelloButton.jsx
import { useState } from 'react';
export default function HelloButton() {
const [count, setCount] = useState(0);
return (
<button
onClick={() => setCount(count + 1)}
aria-label="increment"
className="hello-btn"
>
Clicked {count} times
</button>
);
}
Line-by-line:
useState
hooks into React 18’s concurrent state engine.onClick
triggers an update; automatic batching groups multiple clicks per frame.aria-label
nails basic accessibility.
3 — Mount with createRoot
Open src/main.jsx
:
import { createRoot } from 'react-dom/client';
import HelloButton from './components/HelloButton';
import './index.css';
createRoot(document.getElementById('root')).render(
<HelloButton />
);
Why not ReactDOM.render
? It’s deprecated. createRoot
unlocks concurrent rendering—the marquee React 18 feature.
4 — Live Reload & Validate
Save the file. Your browser should hot-reload, and clicking the button increments the counter without jank even on throttled 3G (DevTools → Network → Slow 3G).
Common Pitfalls & Fixes
Bug | Symptom | Quick Fix |
---|---|---|
Missing file extension in import | “Cannot resolve ‘./components/HelloButton’” | Add .jsx or configure resolve.extensions |
Mixing default & named exports | Component renders blank | export default vs. { HelloButton } —stay consistent |
Event handler fires but state won’t change | Count stuck | Ensure state update uses setter (setCount ) not count++ |
Debug tip: In React 18 strict mode dev builds, functions run twice to catch side-effects. Don’t panic—production renders once.
Remote-Work Insight 🌍
Sidebar, 120 words
Pairing across 12-hour offsets taught me to script everything. I keep acreate-react18
Bash alias that spins up Vite, installs ESLint, and commits the first component—so mentees in Lagos or Taipei start from the same git hash. Fewer “but it works on mine” comments, more code review on logic. Time zones fade when your tooling is reproducible.
Performance & Accessibility Checkpoints
- Lighthouse Audit
Target LCP < 2.5 s. Vite’s dev server isn’t optimized; runnpm run build && npx serve dist
before auditing. - Assistive Tech
Use ChromeVox or NVDA. Confirm the button announces “Clicked 0 times” then updates. React 18 ensures state flushes before announcement thanks to sync hydration. - Color Contrast
If you style.hello-btn
, meet WCAG AA (4.5:1 ratio).
Handy CLI & Tool Table
Command / Tool | Purpose |
---|---|
npm create vite@latest | Bootstrap a React 18 project in 30 s |
npm run dev | Launches Vite’s lightning dev server |
npm run build | Generates optimized production bundle |
npm i -D eslint-plugin-react-hooks | Lints hook usage to avoid infinite loops |
Wrap-Up
We transformed eight lines of JSX into a living browser element—and peeked at the concurrency magic React 18 brings to even the simplest counter. Your next steps? Swap the button for a form, fetch data with useEffect
, or stylize with Tailwind. Drop your first-component triumphs (or catastrophes) in the comments; I read every notification—no matter the time zone.
Leave a Reply