From JSX to Browser with React 18: Your First Component, Demystified

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 PointWhy It HurtsReact 18 Remedy
Legacy tutorials stuck on React 16/17Newcomers copy obsolete APIscreateRoot() gives instant React 18 parity
“It works on my laptop” config driftInconsistent dev envs across time zonesnpx create-vite@latest zero-config starter
Slow first interactionCore Web Vitals penaltiesAutomatic 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

BugSymptomQuick Fix
Missing file extension in import“Cannot resolve ‘./components/HelloButton’”Add .jsx or configure resolve.extensions
Mixing default & named exportsComponent renders blankexport default vs. { HelloButton }—stay consistent
Event handler fires but state won’t changeCount stuckEnsure 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 a create-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

  1. Lighthouse Audit
    Target LCP < 2.5 s. Vite’s dev server isn’t optimized; run npm run build && npx serve dist before auditing.
  2. 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.
  3. Color Contrast
    If you style .hello-btn, meet WCAG AA (4.5:1 ratio).

Handy CLI & Tool Table

Command / ToolPurpose
npm create vite@latestBootstrap a React 18 project in 30 s
npm run devLaunches Vite’s lightning dev server
npm run buildGenerates optimized production bundle
npm i -D eslint-plugin-react-hooksLints 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.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *