JSTAcademy
0 XP
Dashboard
Crash Courses
Environment, Components & Thinking in React
12 min
Basic+150 XP
Crash Courses · Basic

Environment, Components & Thinking in React

Set up Vite + React, master JSX from first principles, and build composable components.
12 min read+150 XP on completionCert: React Crash Course
Tap any word in the text below to start reading from there.

Environment, Components & Thinking in React

Why React? The DOM Mutation Problem

Imagine building a dashboard: a user menu, a data table, a notification badge, and a sidebar. When a user logs in, every element that displays user data needs to update. In vanilla JavaScript that means:

document.querySelector('#nav-username').textContent = user.name
document.querySelector('#avatar').src = user.avatar
document.querySelector('#badge').textContent = notifications.length
document.querySelector('#sidebar-name').textContent = user.name
// ... one line per DOM node, forever

This is imperative UI — you manually describe every mutation. As the app scales, this becomes unmanageable. Miss one update and the UI is inconsistent. Add a new feature and you must trace every element it affects.

React introduces a declarative model: instead of saying "update element X", you say "given this state, the UI looks like this." React computes the minimum DOM changes needed. This is the mental shift that makes React transformative — you focus on what the UI should look like, not how to get there.

Setting Up Your Environment

Create React App is officially deprecated. The modern standard is Vite.

Step 1 — Create the project:

npm create vite@latest my-app -- --template react
cd my-app
npm install
npm run dev

Your app is live at http://localhost:5173. Vite uses native ES modules so hot module replacement (HMR) is near-instant — save a file and the browser updates in milliseconds without reloading.

Step 2 — VS Code extensions to install:

Open VS Code and install these extensions:

  • ES7+ React/Redux/React-Native snippets (by dsznajder): Type rafce and press Tab to scaffold a complete arrow-function component. Saves minutes every day.
  • Prettier - Code Formatter: Set to "Format on Save" for consistent style across your project.

Step 3 — React Developer Tools (browser extension):

Install from the Chrome or Firefox extension store. It adds a Components tab to DevTools. You can inspect the component tree, view props and state in real time, and see exactly why each component re-renders — essential for debugging.

Your Project File Structure

After npm create vite, you get:

my-app/
  src/
    main.jsx             ← entry point — mounts <App /> into index.html
    App.jsx              ← root component rendered into the DOM
    assets/              ← images, SVGs, static files
    components/          ← create this folder for your own components
      Card.jsx
      Button.jsx
      NavBar.jsx
  index.html             ← single HTML page — Vite injects your bundle here
  vite.config.js         ← build configuration
  package.json

Every component lives in a .jsx (or .tsx for TypeScript) file. Components export as named or default exports and import into parent components.

What Is a Component?

A component is a JavaScript function that:

  1. Accepts one argument — an object called props (or no argument if it takes no input)
  2. Returns JSX — a description of the UI to render
// src/components/Card.jsx
export function Card({ title, description, imageUrl }) {
  return (
    <div className="card">
      <img src={imageUrl} alt={title} />
      <h2>{title}</h2>
      <p>{description}</p>
    </div>
  )
}

When React encounters <Card title="React" /> it calls this function, receives JSX, and renders it to the DOM. When props change, React calls the function again, diffs the new JSX against the previous output, and surgically updates only the changed DOM nodes.

JSX Is Not HTML — Three Critical Differences

1. Use `className` not `class`:

// Wrong — class is a reserved keyword in JavaScript
<div class="container">

// Correct
<div className="container">

2. Event handlers are camelCase and receive function references, not strings:

// HTML — lowercase, string handler
<button onclick="handleClick()">

// JSX — camelCase, pass the function directly
<button onClick={handleClick}>
<input onChange={handleChange} onKeyDown={handleKeyDown} />

3. All tags must be explicitly closed:

// Wrong — implicit closing not allowed
<img src="/logo.png">
<input type="text">
<br>

// Correct — self-closing syntax required
<img src="/logo.png" alt="Logo" />
<input type="text" />
<br />

Component Composition — The Real Power of React

Simple components compose into complex UIs by nesting. Props flow down the tree from parent to child:

// src/components/Button.jsx
export function Button({ children, variant = 'primary', onClick }) {
  return (
    <button className={`btn btn-${variant}`} onClick={onClick}>
      {children}
    </button>
  )
}

// src/App.jsx
import { Card } from './components/Card'
import { Button } from './components/Button'

export default function App() {
  return (
    <main className="app">
      <Card
        title="React Crash Course"
        description="Build interactive UIs with hooks and components."
        imageUrl="/courses/react.jpg"
      />
      <Button variant="primary" onClick={() => alert('Enrolled!')}>
        Enroll Now
      </Button>
    </main>
  )
}

The children prop is special — it receives whatever is nested between a component's opening and closing tags. In <Button>Enroll Now</Button>, the string "Enroll Now" becomes props.children. This is how all layout wrapper components work in React.

Importing Between Files

// Named export — import with curly braces
export function Card({ ... }) { ... }
import { Card } from './components/Card'

// Default export — import without curly braces
export default function App() { ... }
import App from './App'

Convention: one component per file. The file name matches the component name. This makes codebases easy to navigate.

0%