Chapters

Hide chapters

React Apprentice

First Edition · web · React 8.0.0 · Visual Studio Code

Section I: Rendering Right

Section 1: 7 chapters
Show chapters Hide chapters

2. Why React Exists
Written by Eli Ganim

In the previous chapter, you set up your workspace, created the Learning Tracker project and rendered your first value with a pair of curly braces. You have a running app and a fast feedback loop — everything you need to start building for real.

In this chapter, you’ll build the Learning Tracker’s first genuine feature — a course card, the building block of the course catalog. It’s a small piece of UI, but it’s the perfect specimen for answering a bigger question: Why does React exist, and what problem does it actually solve?

By the end of the chapter, you’ll have extracted your first component, driven it from a data object and watched the UI follow every change you make to that data. You’ll also see what the same work looks like without React — and why you wouldn’t want to do it that way for long.

Building Your First Course Card

The Learning Tracker’s home screen will eventually show a catalog of courses. Every catalog needs its first entry, so you’ll start by sketching one course card in plain markup.

Replace the entire contents of src/App.tsx with:

import './App.css'

function App() {
  return (
    <main>
      <h1>Learning Tracker</h1>
      <p>Your course catalog starts here.</p>
      <article>
        <h2>React Basics</h2>
        <p>Build interfaces from reusable components.</p>
        <p>Level: Beginner</p>
      </article>
    </main>
  )
}

export default App

Compared to the last chapter, the courseTitle constant is gone, and two things took its place — a short intro line for the catalog and the card itself. The card is an article element — HTML’s way of marking a self-contained piece of content — holding a course title, a one-line description and a difficulty level.

Save the file and check the browser:

The first course card, straight from your markup.
The first course card, straight from your markup.

There’s your card. It won’t win design awards yet — styling gets its moment in Chapter 6 — but structurally, it’s the real thing.

Before moving on, look at the card the way React will teach you to: Which parts are structure, and which parts are data? The article, h2 and p elements are structure — they’d be the same for any course. But “React Basics”, the description and “Beginner” are data. They just happen to be trapped inside the markup. You’ll free them soon.

Extracting Your First Component

Right now, the course card lives inside App. Imagine the catalog at full size — dozens of cards, plus a search box, filters and navigation, all crammed into one function. You’d scroll forever to find anything.

React’s answer is the component — a function whose job is to return a piece of UI. You’ve been using one all along — App is a component. Time to write your own.

In src/App.tsx, add this function above App:

function CourseCard() {
  return (
    <article>
      <h2>React Basics</h2>
      <p>Build interfaces from reusable components.</p>
      <p>Level: Beginner</p>
    </article>
  )
}

It’s the exact card markup from before, wrapped in a function named CourseCard. Nothing else changed — a component really is just a function that returns UI.

Now, replace the whole App function with:

function App() {
  return (
    <main>
      <h1>Learning Tracker</h1>
      <p>Your course catalog starts here.</p>
      <CourseCard />
    </main>
  )
}

Where the article used to sprawl, there’s now a single self-closing tag: <CourseCard />. When React encounters it, it calls your CourseCard function and puts whatever it returns in that spot.

Save the file and look at the browser. Expect no visible change — the page is pixel-for-pixel identical. That’s the mark of a good refactor: You improved the code’s structure without touching its behavior.

Note: The capital C in CourseCard isn’t a style choice — it’s how JSX tells your components apart from built-in HTML elements. Lowercase tags like <article> become real HTML elements; capitalized tags like <CourseCard /> become calls to your functions. Name a component courseCard, and React will treat <courseCard /> as an unknown HTML tag and render your card nowhere.

Components Are Functions That Return UI

Step back and look at what your file describes now, because this shape — a tree of components — is the shape of every React app you’ll ever build:

The Learning Tracker's component tree: App at the root, with elements and components as branches.
The Learning Tracker's component tree: App at the root, with elements and components as branches.

App sits at the root. It returns some plain elements — the heading, the intro line — and one component, CourseCard, which returns elements of its own. React starts at the root, calls each component function it meets and keeps going until it has a complete description of the page, made of nothing but real elements.

Two properties of this model do a lot of heavy lifting:

  • Components compose: Big interfaces are built by combining small components, the way paragraphs build chapters. When the catalog grows a search bar, it’ll be a component. So will the navigation, each page and every card.
  • Components are self-describing: <CourseCard /> reads like what it is. Compare that to scrolling through fifty lines of nested markup to figure out you’re looking at a course card.

For now, CourseCard always returns the same card, which makes it only mildly useful. The next step gives it something real to work with.

Separating Data From Markup

You identified the card’s trapped data earlier: title, description, level. Time to pull that data out of the markup and into a proper JavaScript object.

Still in src/App.tsx, add this above CourseCard:

const course = {
  title: 'React Basics',
  description: 'Build interfaces from reusable components.',
  level: 'Beginner',
  isFavorite: true,
}

This is a plain JavaScript object describing one course. Three of its properties match the card’s visible text. The fourth, isFavorite, is a boolean you’ll put on screen shortly — every tracker needs favorites.

Note: An object groups related values under named properties, written as name: value pairs inside braces. You read one back with a dot: course.title is 'React Basics', and course.isFavorite is true. This is JavaScript, not React — if object syntax feels rusty, take a short detour through a JavaScript refresher before continuing; the rest of the book leans on objects constantly.

Now connect the object to the card. In CourseCard, replace the returned article with:

<article>
  <h2>{course.title}</h2>
  <p>{course.description}</p>
  <p>Level: {course.level}</p>
</article>

The hardcoded text is gone. In its place are curly braces — the same trick you used in Chapter 1 — each reading one property from the object. Notice the last line mixes both worlds: Level: is fixed text, and {course.level} fills in the data.

Save and check the browser: The page looks exactly the same. That’s the point. Same UI, but now the markup describes structure, while the object owns the data. Change the data, and the card changes — no markup edits required. You’ll prove that in a moment.

Letting TypeScript Watch Your Back

First, a quick experiment. You never told TypeScript what shape course has, yet it knows. Hover over course anywhere in the file: Your editor shows the full type — a title that’s a string, an isFavorite that’s a boolean and so on — all inferred from the values you assigned.

To see why that matters, sabotage yourself. In the h2, change course.title to course.titel and save. The browser doesn’t crash — it quietly renders a card with no title at all, because course.titel doesn’t exist and produces nothing. That’s the kind of bug that ships on a Friday.

But look at your editor: titel has a red underline, and hovering over it reveals:

Property 'titel' does not exist on type '{ title: string;
description: string; level: string; isFavorite: boolean; }'.
Did you mean 'title'?

TypeScript compared your typo against the object’s actual shape, flagged the mismatch and even guessed the fix. This is what TypeScript does all book long: it treats your data’s shape as a contract and tells you the moment your code breaks it. Fix the typo back to course.title before moving on.

Showing the Favorite Message

The isFavorite property is still invisible. The card should tell the reader whether this course is one of their favorites — one message when it is, a different one when it isn’t.

In CourseCard, add this above the return:

let favoriteMessage = 'Not in your favorites yet'
if (course.isFavorite) {
  favoriteMessage = 'One of your favorites'
}

This is everyday JavaScript: Start with the default message, then overwrite it when the course is a favorite. Because a component is just a function, you can compute values like this before the return — a pattern you’ll use constantly.

Now display it. Add this line inside the article, below the level:

<p>{favoriteMessage}</p>

Save and check the browser:

The card now reflects the isFavorite boolean.
The card now reflects the isFavorite boolean.

The card proudly reports “One of your favorites”, because isFavorite is true.

Changing the Data

You’ve been told twice that the UI follows the data. Time to see it with your own eyes.

In the course object, make two changes: Set title to 'CSS Layout' and isFavorite to false. Save, and watch the card:

Different data, different card — and you never touched the markup.
Different data, different card — and you never touched the markup.

Both the title and the favorite message changed. Read your edit again: You modified two values in an object. You didn’t touch the article, the braces or the if statement. The description of the UI stayed fixed; the data flowed through it.

This is worth sitting with for a second, because it’s the core habit of React development: When you want the UI to change, you change the data — not the page.

Try one more, and this time predict the outcome before you save: Change level to 'Advanced'. Which lines of the card will change? Just one — the level line — because that’s the only place the markup reads course.level. If your prediction matched, you’re already thinking in React.

Restore the object — title back to 'React Basics', isFavorite back to true, level back to 'Beginner' — and save. The next chapter picks up from exactly this state.

Why React Works This Way

You’ve now experienced React’s approach: describe the UI once, feed it data. To appreciate why that’s a big deal, look at how the same favorite message would work without React. You don’t need to type this — just read it:

const message = document.querySelector('#favorite-message')
if (course.isFavorite) {
  message.textContent = 'One of your favorites'
} else {
  message.textContent = 'Not in your favorites yet'
}

This is the browser’s raw DOM API. The code hunts down the right element, then manually overwrites its text. And it has to run again — all of it — every single time isFavorite changes.

Now scale that up to the finished Learning Tracker. A favorite shows up in at least three places — the message on the card, a favorites counter in the header and a highlight on the My Learning page. In this manual style, every action that touches favorites must remember to update all three spots. Forget one — and eventually someone will — and your UI starts lying to the user: The card says favorite while the counter says otherwise. Bugs like that are miserable to find, because every individual line of code looks correct; it’s the coordination that’s broken.

This style is called imperative: You spell out how to update the page, step by step, and you own every step forever. React’s style is declarative: You state what the UI should look like for the current data, and React works out the how. Your CourseCard never says “find the message and change its text”. It says “the message is whichever of these two strings matches the data”, and that stays true no matter how the data changes. Each of those three favorite displays derives itself from the same data, so they can’t fall out of sync.

If you’ve ever built a spreadsheet, you’ve already worked declaratively. A formula cell doesn’t say “when column B changes, go recalculate me” — it declares what it is (=B2*C2), and the spreadsheet keeps it current. React brings that same arrangement to your UI: Components declare what they are, and React keeps the page current.

Here’s the full picture of how React turns your declaration into pixels:

The render produces a fresh UI description; the commit updates the browser to match.
The render produces a fresh UI description; the commit updates the browser to match.

Data goes in. Your component function runs and returns a description of the UI — that’s what JSX really is, a description, not the real page. React calls that first phase a render: your components run, and out comes a fresh description. Turning that description into actual changes on the page is a second, separate phase called the commit. Rendering works out what the UI should be; committing makes the browser match. Keeping the two apart will pay off later in the book, when you dig into how React decides what to re-render.

A fair question at this point: If React reruns your components to get a fresh description, isn’t that wasteful? It isn’t, for two reasons. First, running a JavaScript function is cheap — it’s touching the real page that’s expensive. Second, React doesn’t rebuild the page from the description; it compares the new description with the previous one and commits only the differences. When your title changed to “CSS Layout”, React updated one heading’s text and left every other element alone. You describe generously; React updates surgically.

One piece of vocabulary completes the picture. Data that changes over the life of your app — favorites toggling, searches typed, courses completed — is called state. Your course object isn’t state yet: You change it by editing source code, and the dev server restarts the world for you. Real state changes while the app runs, at the click of a user — and when it does, React reruns your components with the new data and updates the page. Making that happen is Chapter 8’s job; every chapter until then builds the muscles you’ll need for it.

Challenge: Build Your Dream Course Card

Your turn to fly solo. This challenge has two parts:

  1. Replace the course object’s data with a course you’d genuinely want to take — your own title, description and level, and your honest isFavorite verdict.
  2. Courses have lengths, so add a duration property to the object — a string like '6 hours' — and give the card a new line that renders it — something like Duration: 6 hours.

Two hints:

  • The new property is one line in the object, and the new line in the card looks a lot like the Level line.
  • Fixed label text lives outside the braces; the data value lives inside them.

You’ll find a complete solution in the challenge folder of this chapter’s materials.

Key Points

  • A component is a function that returns a description of UI, and its name must start with a capital letter.
  • Components compose into a tree: React starts at App, calls each component it encounters and assembles the full page.
  • Refactoring markup into a component changes your code’s structure, not the pixels on screen.
  • Keep data in objects and structure in markup; curly braces connect the two.
  • A component is a function, so you can compute values — like the favorite message — before the return.
  • To change the UI, change the data, not the page.
  • Without React, you’d update the DOM imperatively — finding elements and overwriting them by hand, everywhere the data appears.
  • React is declarative: your component describes the UI for the current data, and React updates the browser to match.
  • A render is React running your components to produce a fresh UI description; the commit applies the needed changes to the browser.
  • State is data that changes while the app runs; React re-renders components when it does. You’ll create your first state in Chapter 8.
  • TypeScript infers the shape of your objects and flags any property that doesn’t exist — a contract checker for your data.

Where to Go From Here?

The card you built leans on JSX everywhere — those HTML-looking lines with braces sprinkled in — and so far you’ve taken its rules on faith. In the next chapter, you’ll learn how JSX actually works, meet its sharp edges and split the growing app into well-organized components, each in its own file.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.