cf.completefrontend
Open lab My progress
THE REACT FIELD GUIDE

Your first React app

Build a tip calculator in React step by step: split the screen into components, show data, handle a click, and update the screen with state, live as you edit.

By the end, you can
  • 01
    Split a screen into componentsLook at a design, name its parts, and write each one as a function that returns markup.
  • 02
    Show data and handle a clickPut values into markup with curly braces, pass them to a component as props, and run a function when a button is clicked.
  • 03
    Update the screen with stateExplain why changing a plain variable doesn't change the screen, and use useState so React shows the new value.

A tip calculator, built in five steps

In this lesson you build a whole React app: a tip calculator. You type the bill, pick a tip, and it shows the tip, the total, and what each person pays. You'll build it in small steps, and each step adds one idea. Every step is live: you see its result, you can click it, and you can change its code.

You start where Setting up a React project left off, with the starter replaced by your own App:

Where you start: App.jsxPop out in the code editor (opens in a new tab)JSX
export default function App() {  return <h1>Tip calculator</h1>;}
ResultLoading…

Line 1 defines a component called App and exports it, so main.jsx can show it. Line 2 returns what the screen shows: one heading. That's the whole app so far. By the end of step 4, the screen looks like this, and each labelled part is a component of its own:

A page window showing the tip calculator: the heading, Bill: $48.00, tip 15%, three buttons 10%, 15%, and 20%, then Tip: $7.20 and Total: $55.20. Arrows from the right name the parts: App is the whole page, TipButtons is the row of buttons, and Summary is the tip and total.pageTip calculatorBill: $48.00, tip 15%10%15%20%Tip: $7.20Total: $55.20AppTipButtonsSummary
One screen, three components. App draws the whole page, TipButtons draws the row of buttons, and Summary draws the tip and the total.

The steps:

  1. Split the screen into components.
  2. Show data: work out the tip and total, and put them on the screen.
  3. Handle a click on a tip button.
  4. Remember the chosen tip with state, so the screen updates.
  5. Put it together: type the bill, and split it between people.

Each step previews an idea that a later lesson teaches properly. Here you only need enough to make the app work, and each step says where you'll learn the rest.

Real-life analogyA café's order ticket

In a café, pointing at the menu doesn't make food appear. The waiter writes your choice on the order ticket, and the kitchen makes what the ticket says. If the choice never reaches the ticket, the kitchen never hears about it.

In real life: The sections of the menu board
In React: Components: TipButtons, Summary
In real life: The prices written on the board
In React: Data shown with curly braces: ${tip.toFixed(2)}
In real life: A customer pointing at an item
In React: A click on a button, handled by onClick
In real life: The waiter writing it on the ticket
In React: setTipPercent(20): changing state
In real life: The kitchen making the order from the ticket
In React: React calling App again and updating the page
The main idea

A React app is components that turn data into what the screen shows. When something happens, like a click, an event handler changes state, and React calls your components again and updates the page to match.

Step 1: split the screen into components

Look at the picture again and name the parts: a row of tip buttons, and a summary with the tip and total. Each part becomes a component: a function whose name starts with a capital letter and returns markup. For now the numbers are typed in by hand, and the buttons do nothing.

Step 1: three components, no data yetPop out in the code editor (opens in a new tab)JSX
function TipButtons() {  return (    <div>      <button>10%</button>      <button>15%</button>      <button>20%</button>    </div>  );} function Summary() {  return (    <div>      <p>Tip: <strong>$7.20</strong></p>      <p>Total: <strong>$55.20</strong></p>    </div>  );} export default function App() {  return (    <div className="calculator">      <h2>Tip calculator</h2>      <p>Bill: $48.00, tip 15%</p>      <TipButtons />      <Summary />    </div>  );}
ResultLoading…
  1. Lines 1 to 9 are TipButtons. It returns a <div> with three buttons.
  2. Lines 11 to 18 are Summary. It returns the tip and the total, written in by hand.
  3. Lines 20 to 29 are App, the component main.jsx shows. It returns a heading, a line about the bill, and then, on lines 25 and 26, <TipButtons /> and <Summary />. Written like tags, they tell React to call those functions and put what they return there.

The result looks finished, but nothing works yet. Press Edit & run and copy line 25 so it appears twice: two rows of buttons show. A component is written once and used as many times as you like.

All three components live in one file for now; step 5 moves two of them into files of their own. Naming components, nesting them, and moving them between files is what Your first component teaches properly. The markup itself is JSX, which Writing markup with JSX covers.

Step 2: show data with curly braces

The numbers in step 1 are typed in by hand, so they're wrong as soon as the bill changes. In step 2, JavaScript works them out from two values, and the components show the results:

Step 2: the numbers come from dataPop out in the code editor (opens in a new tab)JSX
const bill = 48;const tipPercent = 15; function TipButtons() {  return (    <div>      <button>10%</button>      <button>15%</button>      <button>20%</button>    </div>  );} function Summary({ tip, total }) {  return (    <div>      <p>Tip: <strong>${tip.toFixed(2)}</strong></p>      <p>Total: <strong>${total.toFixed(2)}</strong></p>    </div>  );} export default function App() {  const tip = (bill * tipPercent) / 100;  const total = bill + tip;   return (    <div className="calculator">      <h2>Tip calculator</h2>      <p>Bill: ${bill.toFixed(2)}, tip {tipPercent}%</p>      <TipButtons />      <Summary tip={tip} total={total} />    </div>  );}
ResultLoading…
  1. Lines 1 and 2 are the data: a bill of 48 and a tip of 15 percent.
  2. Lines 24 and 25, inside App, work out the tip, 48 * 15 / 100, which is 7.2, and the total, 55.2. It's plain JavaScript that runs each time React calls App.
  3. Line 30 puts values into the markup with curly braces: {tipPercent} shows 15. Inside the braces is JavaScript; the $ before {bill.toFixed(2)} is plain text, and toFixed(2) writes the number with two decimals, 48.00.
  4. Line 32 passes the tip and total to Summary: tip={tip} and total={total}. Values written on a component's tag like this are its props.
  5. Line 14 receives them. React passes the props as one object, and { tip, total } takes the two values out of it with destructuring. Lines 17 and 18 show them: $7.20 and $55.20.
A window named App holding bill = 48, tipPercent = 15, and tip = 7.2. An arrow labelled props leads to a function card, Summary, which gets tip and total. Another arrow leads to a page window showing Tip: $7.20 and Total: $55.20.Appbill = 48tipPercent = 15tip = 7.2propsSummary{ tip, total }pageTip: $7.20Total: $55.20
App works out tip and total from bill and tipPercent, and passes them to Summary as props. Summary only shows what it's given, with two decimals.

Press Edit & run and change the bill on line 1 to 60. The bill line, the tip, and the total all follow: $9.00 and $69.00. You changed the data, and every place that shows it changed with it, the idea from Why React?.

Curly braces get a lesson of their own, JavaScript in JSX with curly braces, and so do props, Passing props to a component.

Step 3: handle a click

Now the buttons need to do something. In React you give a button a function to run when it's clicked, with onClick. A first try changes the tip with an ordinary variable:

Step 3: a click changes a plain variablePop out in the code editor (opens in a new tab)JSX
const bill = 48; function TipButtons({ onChoose }) {  return (    <div>      <button onClick={() => onChoose(10)}>10%</button>      <button onClick={() => onChoose(15)}>15%</button>      <button onClick={() => onChoose(20)}>20%</button>    </div>  );} function Summary({ tip, total }) {  return (    <div>      <p>Tip: <strong>${tip.toFixed(2)}</strong></p>      <p>Total: <strong>${total.toFixed(2)}</strong></p>    </div>  );} export default function App() {  let tipPercent = 15;   function choose(percent) {    tipPercent = percent;    console.log("tipPercent is now", tipPercent);  }   const tip = (bill * tipPercent) / 100;  const total = bill + tip;   return (    <div className="calculator">      <h2>Tip calculator</h2>      <p>Bill: ${bill.toFixed(2)}, tip {tipPercent}%</p>      <TipButtons onChoose={choose} />      <Summary tip={tip} total={total} />    </div>  );}
ResultLoading…
  1. Line 3: TipButtons now takes one prop, onChoose. A prop can be a function, too.
  2. Lines 6 to 8 give each button an onClick. Its value is an arrow function, () => onChoose(20), which React keeps and calls when you click. The click is an event, and the function is its event handler.
  3. Line 23 makes tipPercent a plain variable, starting at 15. Lines 25 to 28 define choose, which sets it and prints it to the console.
  4. Line 37 passes choose to TipButtons as onChoose. So clicking 20% runs choose(20).

Click 20% in the result. The console under it says tipPercent is now 20, but the screen still says tip 15% and $7.20. Click 10%: the console changes, the screen doesn't.

A box named tipPercent holds a crossed-out 15 and a new 20. The console window says tipPercent is now 20. The page window still says tip 15% and Tip: $7.20. Labels: the variable changed; the screen didn't.1520tipPercentafter the clickconsoletipPercent is now 20pageBill: $48.00, tip 15%Tip: $7.20the variable changedthe screen didn't
Clicking 20% sets the plain variable to 20, and the console proves it. But React wasn't told, so it doesn't call App again, and the page still says tip 15%.

Two things go wrong:

  • React isn't told. Changing a variable is ordinary JavaScript. Nothing tells React that the screen should change, so it doesn't call App again, and lines 30 to 40 never run with the new value.
  • The value isn't kept. Even if React did call App again, line 23 would run again and set tipPercent back to 15. Each call of a component starts its variables fresh.

Events, handlers, and passing them as props are what Responding to events teaches properly.

Step 4: remember the choice with state

The fix for both problems is state: a value that React remembers for a component between calls, and a function that changes it and tells React to call the component again. You ask for it with useState:

Step 4: the tip is statePop out in the code editor (opens in a new tab)JSX
import { useState } from "react"; const bill = 48; function TipButtons({ onChoose }) {  return (    <div>      <button onClick={() => onChoose(10)}>10%</button>      <button onClick={() => onChoose(15)}>15%</button>      <button onClick={() => onChoose(20)}>20%</button>    </div>  );} function Summary({ tip, total }) {  return (    <div>      <p>Tip: <strong>${tip.toFixed(2)}</strong></p>      <p>Total: <strong>${total.toFixed(2)}</strong></p>    </div>  );} export default function App() {  const [tipPercent, setTipPercent] = useState(15);   const tip = (bill * tipPercent) / 100;  const total = bill + tip;   return (    <div className="calculator">      <h2>Tip calculator</h2>      <p>Bill: ${bill.toFixed(2)}, tip {tipPercent}%</p>      <TipButtons onChoose={setTipPercent} />      <Summary tip={tip} total={total} />    </div>  );}
ResultLoading…
  1. Line 1 imports useState from React. Functions whose names start with use are called hooks.
  2. Line 25 asks React for a piece of state, starting at 15. useState gives back two things in an array: the current value, tipPercent, and a function that sets a new one, setTipPercent. The brackets take both out with array destructuring.
  3. Line 34 passes setTipPercent to TipButtons as onChoose. So clicking 20% now runs setTipPercent(20).
  4. Everything else is the same as step 2: lines 27 and 28 work out the tip and total, and Summary shows them.

Click 20%. Now the screen says tip 20%, $9.60, and $57.60. Click 10%: $4.80 and $52.80.

Four steps from left to right. A card, click 20%. An arrow to a function card, setTipPercent(20). An arrow to a function card, App(), labelled tipPercent: 20. An arrow to a page window showing 20% and $9.60.click 20%your clicksetTipPercent(20)sets stateApp()tipPercent: 20called againpage20%$9.60only changes
A click calls setTipPercent(20). React remembers 20 and calls App again. App works out the new tip and total, and React changes only the pieces of text that differ.

Here is what happens on that click. setTipPercent(20) stores 20 and tells React this component needs a new render. React calls App again; this time line 25 gives back 20, so lines 27 and 28 work out a tip of 9.6 and a total of 57.6, and the markup describes the new screen. React compares it with the last one and changes only what differs. The playground below runs the same code on this page and shows you exactly what React changed:

Playground: follow one click through React
The app (step 4)

Tip calculator

Bill: $48.00, tip 15%

Tip: $7.20

Total: $55.20

What React changednothing yet

No click yet.

Try it yourself

Click 10%, 15%, or 20% in the app. Try the same button twice.

Click a tip button in the app. The panel lists every piece of text React changed on the page for that click.

The app is step 4's code, running with React on this page. The list is what a MutationObserver saw change inside the app after your last click. Reset starts the app again at 15%.

Click 20%: React changes three pieces of text, the 15 in the bill line, the tip, and the total. The heading, the bill, and the buttons stay as they are. Click 20% again: tipPercent is already 20, so nothing on the page changes. How React works: a first look explains this compare-then-change step.

How to read the table: each row asks the same question of step 3's plain variable and step 4's state.

A plain variable or state
QuestionA plain variable (step 3)State (step 4)
Does React remember it between calls of App?No. Each call runs let tipPercent = 15 again.Yes. React keeps it and gives it back on the next call.
Does changing it make React call App again?No. React doesn't know it changed.Yes. setTipPercent(20) asks React for a new render.
What does the screen show after a click?The old value: tip 15%.The new value: tip 20%, with the new tip and total.

State is the biggest idea in this lesson, and the course gives it several lessons, starting with State: a component's memory.

Step 5: the finished app

The last step finishes the app. You can type the bill, the chosen tip is marked, and the bill is split between people. The two smaller components move into files of their own, so the example has tabs: App.jsx, TipButtons.jsx, Summary.jsx, and styles.css.

Step 5: the finished tip calculatorPop out in the code editor (opens in a new tab)JSX
import { useState } from "react";import TipButtons from "./TipButtons.jsx";import Summary from "./Summary.jsx"; export default function App() {  const [bill, setBill] = useState("48");  const [tipPercent, setTipPercent] = useState(15);  const [people, setPeople] = useState(1);   const amount = Number(bill) || 0;  const tip = (amount * tipPercent) / 100;  const total = amount + tip;   return (    <main className="calculator">      <h1>Tip calculator</h1>      <label>        Bill ($){" "}        <input          type="number"          value={bill}          onChange={(event) => setBill(event.target.value)}        />      </label>      <TipButtons selected={tipPercent} onChoose={setTipPercent} />      <p>        People: {people}{" "}        <button onClick={() => setPeople(people - 1)} disabled={people === 1}>          Remove a person        </button>        <button onClick={() => setPeople(people + 1)}>Add a person</button>      </p>      <Summary tip={tip} total={total} people={people} />    </main>  );}
ResultLoading…

In App.jsx:

  • Lines 2 and 3 import the two components from their files.
  • Lines 6 to 8 keep three pieces of state: the bill, the tip percent, and the number of people. The bill starts as the text "48", because a text box always holds text. Line 10 turns it into a number with Number, and uses 0 while the box is empty.
  • Lines 19 to 23 are the text box. value={bill} shows the state, and onChange runs on every key you type, setting the state to what's in the box. It's a second kind of event; forms get their own lessons, starting with Reacting to input with state.
  • Line 25 passes selected as well, so the buttons know which tip is chosen. Lines 28 and 31 change the number of people, and line 28's button is turned off while there's only one person.

In TipButtons.jsx, line 1 lists the choices and line 6 makes one button per choice with map (Rendering lists explains the key on line 8). Line 9 sets aria-pressed on the chosen button, which tells screen readers it's chosen and lets styles.css outline it. In Summary.jsx, line 6 divides the total by the number of people.

Try it: type 60 as the bill, choose 20%, and press Add a person twice. The tip is $12.00, the total $72.00, and each of the 3 people pays $24.00. Then press Edit & run and make it yours: add a 25% choice to line 1 of TipButtons.jsx, or change the starting bill on line 6 of App.jsx.

Why the earlier steps use a div and an h2

The finished app wraps everything in <main> with an <h1>, the right tags for a page's main content and its title. Steps 1 to 4 used a <div> and an <h2>, so the playground could show the step 4 app inside this page, which has its own <main> and title.

The same four steps in another app

Most React features you'll build follow the same four steps. Here is a different one, a tea order where you choose how many cups. Click Add one a few times:

A tea order, built with the same four stepsPop out in the code editor (opens in a new tab)JSX
import { useState } from "react"; function Price({ amount }) {  return <strong>${amount.toFixed(2)}</strong>;} export default function App() {  const [quantity, setQuantity] = useState(1);  const price = 3.5;   return (    <div>      <h2>Green tea</h2>      <p>        {quantity} × $3.50 = <Price amount={quantity * price} />      </p>      <button onClick={() => setQuantity(quantity + 1)}>Add one</button>    </div>  );}
ResultLoading…

Lines 3 to 5 are a component, Price, that shows an amount with two decimals. Line 8 keeps the quantity in state, starting at 1, and line 9 is the price of one cup. Line 15 shows data with curly braces and passes the line's price to Price as a prop. Line 17 handles a click by setting the state. After two clicks it says 3 × $3.50 = $10.50.

How to read the table: each row is one of the four steps, what it adds, and a line from the tip calculator that does it.

The four steps
StepWhat it addsA line that does it
ComponentsName the parts of the screen and write each as a function.function Summary() { … }
DataWork out values in JavaScript and show them with curly braces, or pass them as props.<Summary tip={tip} total={total} />
An eventGive a button a function to run when it's clicked.onClick={() => onChoose(20)}
StateKeep a value React remembers, and set it to show a new screen.const [tipPercent, setTipPercent] = useState(15);
Which step is this line?
  • function Summary({ tip, total }) {
  • <Summary tip={tip} total={total} />
  • <strong>${tip.toFixed(2)}</strong>
  • const tip = (bill * tipPercent) / 100;
  • onClick={() => onChoose(20)}
  • onChange={(event) => setBill(event.target.value)}
  • const [tipPercent, setTipPercent] = useState(15);
  • <TipButtons onChoose={setTipPercent} />
Try it yourself
0 of 8 correct

Each card is a line from the tip calculator. Sort it by what it does: a component, showing data, handling an event, or state.

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Common mix-ups

  • "Changing a variable updates the screen." No. React only calls your component again when state changes. Step 3's variable changed, and the screen didn't.
  • "onClick={choose(20)} runs choose when I click." No. It calls choose(20) right away, while React draws the button. Give onClick a function: onClick={() => choose(20)}.
  • "After setTipPercent(20), tipPercent is 20 on the next line." No. The set function asks for a new render. tipPercent is 20 in the next call of App, not in the one that's running. State as a snapshot explains why.
  • "React redraws the whole page after a click." No. It calls your components again, compares, and changes only what differs: three pieces of text in the playground.
  • "Each component needs its own file." No. Steps 1 to 4 kept all three in one file. Separate files help once a component is used in many places or grows long.
  • "I can call useState anywhere, like inside the click handler." No. Call hooks at the top of your component, as line 25 does in step 4. The rules of hooks explains why.

Practice exercises

Each exercise works on the calculator, or a small piece of it. Press Edit & run to change the code, and use the result to check your answer.

Exercise 1 · Warm-upPredict the total

This is step 2 with a different bill and tip, on lines 1 and 2. What total does the page show? Work it out first.

const bill = 40;
const tipPercent = 20;

function TipButtons() {
  return (
    <div>
      <button>10%</button>
      <button>15%</button>
      <button>20%</button>
    </div>
  );
}

function Summary({ tip, total }) {
  return (
    <div>
      <p>Tip: <strong>${tip.toFixed(2)}</strong></p>
      <p>Total: <strong>${total.toFixed(2)}</strong></p>
    </div>
  );
}

export default function App() {
  const tip = (bill * tipPercent) / 100;
  const total = bill + tip;

  return (
    <div className="calculator">
      <h2>Tip calculator</h2>
      <p>Bill: ${bill.toFixed(2)}, tip {tipPercent}%</p>
      <TipButtons />
      <Summary tip={tip} total={total} />
    </div>
  );
}

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · Warm-upStart at 20 percent

    Make the calculator start at 20% instead of 15%. Before you click anything, what does the Tip line show?

    import { useState } from "react"; const bill = 48; function TipButtons({ onChoose }) {  return (    <div>      <button onClick={() => onChoose(10)}>10%</button>      <button onClick={() => onChoose(15)}>15%</button>      <button onClick={() => onChoose(20)}>20%</button>    </div>  );} function Summary({ tip, total }) {  return (    <div>      <p>Tip: <strong>${tip.toFixed(2)}</strong></p>      <p>Total: <strong>${total.toFixed(2)}</strong></p>    </div>  );} export default function App() {  const [tipPercent, setTipPercent] = useState(15);   const tip = (bill * tipPercent) / 100;  const total = bill + tip;   return (    <div className="calculator">      <h2>Tip calculator</h2>      <p>Bill: ${bill.toFixed(2)}, tip {tipPercent}%</p>      <TipButtons onChoose={setTipPercent} />      <Summary tip={tip} total={total} />    </div>  );}
    ResultLoading…

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeAdd a 25% button

      Add a fourth tip button, 25%. After you click it, what does the Tip line show?

      import { useState } from "react"; const bill = 48; function TipButtons({ onChoose }) {  return (    <div>      <button onClick={() => onChoose(10)}>10%</button>      <button onClick={() => onChoose(15)}>15%</button>      <button onClick={() => onChoose(20)}>20%</button>    </div>  );} function Summary({ tip, total }) {  return (    <div>      <p>Tip: <strong>${tip.toFixed(2)}</strong></p>      <p>Total: <strong>${total.toFixed(2)}</strong></p>    </div>  );} export default function App() {  const [tipPercent, setTipPercent] = useState(15);   const tip = (bill * tipPercent) / 100;  const total = bill + tip;   return (    <div className="calculator">      <h2>Tip calculator</h2>      <p>Bill: ${bill.toFixed(2)}, tip {tipPercent}%</p>      <TipButtons onChoose={setTipPercent} />      <Summary tip={tip} total={total} />    </div>  );}
      ResultLoading…

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · PracticeFix the button that breaks the app

        This counter breaks as soon as it starts. Press Edit & run: the result shows an error instead of the app. Read it, find the mistake on line 9, and fix it. Then click Add a person twice. What does the page say?

        import { useState } from "react";
        
        export default function App() {
          const [people, setPeople] = useState(1);
        
          return (
            <p>
              People: {people}{" "}
              <button onClick={setPeople(people + 1)}>Add a person</button>
            </p>
          );
        }

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · ChallengeSplit the bill

          Add an Add a person button and an "Each person pays" line under the total. At 15% with 3 people, what does each person pay?

          import { useState } from "react"; const bill = 48; function TipButtons({ onChoose }) {  return (    <div>      <button onClick={() => onChoose(10)}>10%</button>      <button onClick={() => onChoose(15)}>15%</button>      <button onClick={() => onChoose(20)}>20%</button>    </div>  );} function Summary({ tip, total }) {  return (    <div>      <p>Tip: <strong>${tip.toFixed(2)}</strong></p>      <p>Total: <strong>${total.toFixed(2)}</strong></p>    </div>  );} export default function App() {  const [tipPercent, setTipPercent] = useState(15);   const tip = (bill * tipPercent) / 100;  const total = bill + tip;   return (    <div className="calculator">      <h2>Tip calculator</h2>      <p>Bill: ${bill.toFixed(2)}, tip {tipPercent}%</p>      <TipButtons onChoose={setTipPercent} />      <Summary tip={tip} total={total} />    </div>  );}
          ResultLoading…

          Answer, then press Check. Spacing and letter case don’t matter.

            Exercise 6 · ChallengeShow which tip is chosen

            Turn off the button for the tip that's already chosen, so you can see which one it is. After you click 10%, which button is turned off?

            import { useState } from "react"; const bill = 48; function TipButtons({ onChoose }) {  return (    <div>      <button onClick={() => onChoose(10)}>10%</button>      <button onClick={() => onChoose(15)}>15%</button>      <button onClick={() => onChoose(20)}>20%</button>    </div>  );} function Summary({ tip, total }) {  return (    <div>      <p>Tip: <strong>${tip.toFixed(2)}</strong></p>      <p>Total: <strong>${total.toFixed(2)}</strong></p>    </div>  );} export default function App() {  const [tipPercent, setTipPercent] = useState(15);   const tip = (bill * tipPercent) / 100;  const total = bill + tip;   return (    <div className="calculator">      <h2>Tip calculator</h2>      <p>Bill: ${bill.toFixed(2)}, tip {tipPercent}%</p>      <TipButtons onChoose={setTipPercent} />      <Summary tip={tip} total={total} />    </div>  );}
            ResultLoading…

            Answer, then press Check. Spacing and letter case don’t matter.

              Check your understanding

              For each code question, ask: is this value state or a plain variable, and does the click tell React? Press Edit & run on a question's code to check.

              The Your first React app quiz · 7 questionsScore: first tries count
              1. Question 1 of 7You click Add a person twice. What does this page show?

                Read the code, then predictPop out in the code editor (opens in a new tab)JSX
                export default function App() {
                  let people = 1;
                
                  function addPerson() {
                    people = people + 1;
                  }
                
                  return (
                    <p>
                      People: {people}
                      <button onClick={addPerson}>Add a person</button>
                    </p>
                  );
                }

                Choose an answer to see the explanation.

              2. Question 2 of 7This version keeps people in state. What does it show after two clicks?

                Read the code, then predictPop out in the code editor (opens in a new tab)JSX
                import { useState } from "react";
                
                export default function App() {
                  const [people, setPeople] = useState(1);
                
                  return (
                    <p>
                      People: {people}
                      <button onClick={() => setPeople(people + 1)}>Add a person</button>
                    </p>
                  );
                }

                Choose an answer to see the explanation.

              3. Question 3 of 7Which onClick gives the button a function to run when it's clicked?

                Choose an answer to see the explanation.

              4. Question 4 of 7What does useState(15) give back?

                Choose an answer to see the explanation.

              5. Question 5 of 7A click calls setTipPercent(20). What does React do next?

                Choose an answer to see the explanation.

              6. Question 6 of 7What does this page show?

                Read the code, then predictPop out in the code editor (opens in a new tab)JSX
                function Summary({ tip, total }) {
                  return (
                    <p>
                      Tip ${tip.toFixed(2)}, total ${total.toFixed(2)}
                    </p>
                  );
                }
                
                export default function App() {
                  return <Summary tip={6} total={46} />;
                }

                Choose an answer to see the explanation.

              7. Question 7 of 7Why split the calculator into TipButtons and Summary instead of one big App?

                Choose an answer to see the explanation.

              Key takeaways

              • Start from the screen: name its parts, and write each as a component, a capitalized function that returns markup.
              • Work out values with plain JavaScript, show them with curly braces, and pass them to other components as props.
              • Give a button a function to run later with onClick={() => …}. Writing onClick={f()} calls it right away.
              • Changing a plain variable doesn't change the screen: React isn't told, and the next call starts it fresh.
              • useState gives a value React remembers and a set function. Setting it makes React call the component again and change only what differs on the page.

              Remember the one-liner.
              Components show data; events set state; React calls the components again and updates the page.

              Coming next: Your first component. It starts the Describing the UI stage and teaches components properly: writing them, nesting them, and moving them into their own files.

              CompleteFrontend Clear concepts. Working examples.