Components, JSX and Props

First lesson of the React course, free to read: about 16 minutes, 3 exercises and 3 quiz questions. This is the catalogue's base lesson; in the student space, it is rewritten for your profile.

Objectives

  • Write function components that return JSX
  • Pass data to components with props and children
  • Apply the rules of JSX (expressions, attributes, fragments)

Function componentsJSXProps and children

Components, JSX and Props

React is a JavaScript library for building interfaces out of components: functions that receive data and describe what should be displayed. When the data changes, React updates the DOM for you.

Starting a project

Create React App is deprecated. To learn, use Vite; for a full application, a framework such as Next.js or React Router.

npm create vite@latest ma-boutique -- --template react
cd ma-boutique && npm install && npm run dev

The current template installs React 19.3 and Vite 8; npm run lint runs oxlint, a linter that enforces, among other things, the rules of hooks.

A first component

function Bienvenue() {
  return <h1>Welcome to the shop</h1>;
}

export default function App() {
  return (
    <main>
      <Bienvenue />
      <Bienvenue />
    </main>
  );
}

A component is a function whose name starts with a capital letter (otherwise React takes it for an HTML tag). You use it like a tag: <Bienvenue />.

The rules of JSX

JSX looks like HTML but it is compiled into JavaScript (<h1> becomes a call to a React function). Hence a few rules:

function Fiche() {
  const nom = "City bike";
  const prix = 499;
  return (
    <>                                   {/* fragment: a single parent, without a needless div */}
      <h2 className="titre">{nom}</h2>   {/* className, not class */}
      <p>{prix * 1.2} € incl. VAT</p>    {/* any expression between braces */}
      <label htmlFor="qte">Quantity</label>
      <input id="qte" type="number" defaultValue={1} />  {/* tags are always closed */}
      <p style={{ color: "green" }}>In stock</p>          {/* style: an object */}
    </>
  );
}

Between braces you put an expression (variable, calculation, function call, ternary), not an if or for statement.

Props

Props are a component’s parameters. You receive them in an object, usually destructured:

function CarteProduit({ nom, prix, enStock = true }) {  // default value
  return (
    <article>
      <h2>{nom}</h2>
      <p>{prix} €</p>
      {!enStock && <p>Out of stock</p>}
    </article>
  );
}

<CarteProduit nom="Casque" prix={39} enStock={false} />

Strings are passed in quotes, every other value between braces: prix={39}, enStock={false}, options={{ couleur: "rouge" }}.

Props are read-only: a component must never modify them.

children

What is placed between the opening and closing tags arrives in the children prop:

function Carte({ titre, children }) {
  return (
    <section className="carte">
      <h2>{titre}</h2>
      {children}
    </section>
  );
}

<Carte titre="Delivery">
  <p>Free on orders over €50.</p>
</Carte>

This is the basis of composition: small generic components assembled into complete interfaces.

Pure components

A component must behave like a pure function: with the same props, it returns the same JSX, without modifying any outside variable or calling any API during rendering. Side effects belong in event handlers or effects (lesson 4). In development mode, <StrictMode> deliberately calls your components twice to reveal impurities.

Key takeaways

  • Component = a Capitalized function that returns JSX.
  • {expression}, className, closed tags, a single parent.
  • Read-only props, children for composing.

Exercises

Solutions and tests stay on the server. In the student space, your code is run and checked, and the tutor gives hints before the solution.

  1. CodeDifficulty 12 hints

    Product card

    Write the component CarteProduit({ nom, prix, enStock = true }) which displays:

    • an <article> containing an <h2> with the name;
    • a paragraph with the price formatted by formaterPrix(prix) (provided);
    • a paragraph Rupture de stock only if enStock is false;
    • a button Ajouter au panier, disabled (disabled) when out of stock.
    const formaterPrix = (p) =>
      new Intl.NumberFormat("fr-FR", { style: "currency", currency: "EUR" }).format(p);
    
    export function CarteProduit({ nom, prix, enStock = true }) {
      // TODO
    }
  2. CodeDifficulty 1JavaScript in the browser1 hint

    Format a price (executed)

    A pure function used by your components. Write formaterPrix(prix) which returns the price in French format in euros with Intl.NumberFormat (12.5 → "12,50 €").

    Note: Intl inserts a non-breaking space before €; the tests normalize whitespace.

    function formaterPrix(prix) {
      // TODO
    }
  3. Multiple choiceDifficulty 11 hint

    JSX rules

    Which of these snippets is valid JSX?

    • <div class="carte"><img src={url}></div>
    • <><label htmlFor="q">Search</label><input id="q" /></>
    • <p>{if (ok) { "Oui" }}</p>
    • <h1>Title</h1><p>Text</p> (returned side by side with no parent)

End-of-lesson quiz

  1. Why must a component’s name start with a capital letter?

    • Only as an aesthetic convention
    • So that React can tell it apart from a native HTML tag
    • So that it is exported automatically
  2. What does the children prop contain?

    • The child components declared in the file
    • The content placed between the component's opening and closing tags
    • The list of props
  3. Can a component modify its props?

    • Yes, it's the normal way to update the display
    • No, props are read-only
    • Yes, but only children

The rest of the course

  1. State with useState and Events18 min
  2. Lists, Conditional Rendering and Shared State18 min
  3. Effects, Synchronization and Data Loading20 min
  4. useReducer, Context and Custom Hooks20 min
  5. Forms and Actions with React 1920 min

React · Advanced · 3 h 22 min