Components and state
How frameworks build a page from components and redraw them from the state, shown with the same small feature written in plain JavaScript, React, Vue and Svelte.
What a framework adds
The lesson Behaviour showed why a page that changes a lot should keep its data in one place, and redraw the screen from it. That's the main reason frameworks exist. Whatever the framework, the work rests on three ideas.
Take a weather app. Its screen is made of components: a search box, today's forecast, and a card for each day of the week. The day card is written once and used seven times, each time with different data: Monday, 14°C, rain; Tuesday, 17°C, sun. The data the screen is drawn from is the state: the city, the units (°C or °F) and the forecast. It's kept near the top of the page and passed down to the components that need it. When you choose another city, the state changes, and the framework redraws every component that uses it. Nobody updates the seven cards one by one.
The diagram shows this page as a tree of components, with the state at the top.
Swipe sideways to see the whole figure.
Cheat sheet
- Frameworkframework
- ready-made code, such as React, Vue or Svelte, that redraws the screen from the state automatically.
- Componentcomposant
- a reusable piece of a page, such as a button or a card, designed once and used everywhere.
- Stateétat
- the data that a page keeps in one place, such as the number of passengers, from which the screen is drawn.
- Renderrendu
- to draw the screen again from the state, so that every part that shows the data is up to date.
Components
A component holds everything about one piece of the screen: its HTML structure, its style and its behaviour. On a recipe site, the rating stars might be a component. They appear on the recipe cards, on each recipe's page and under each review. Each time, the component receives its own data: four stars, 128 reviews. Developers call these values props, short for properties.
The benefit comes when something changes. If screen readers can't read the stars, a developer fixes the component once, and every page that uses it is fixed. When the same piece is copied instead, each copy has to be changed by hand, and one is always missed. Components also fit inside each other: the stars sit inside a recipe card, the cards inside a list, and the list inside the page. In the code, their names start with a capital letter, such as <RecipeCard> or <Stars>.
Designers use the same word. The lesson Components and states shows the components a designer draws. In a well-run project, the designer's list and the developer's list are the same, so a change in the design file has an obvious place in the code.
Cheat sheet
- Componentcomposant
- a reusable piece of a page, such as a button or a card, designed once and used everywhere.
- Propsprops, propriétés
- the data that one use of a component receives, such as the number of stars and of reviews.
- Screen readerlecteur d'écran
- software that reads a page aloud, so that blind people and people with poor sight can use it.
- Component librarybibliothèque de composants
- the set of all the components of a site, each with its variants and states.
State, and where it lives
State has to live somewhere, and each place lasts for a different time. Some state belongs to one component's memory, such as whether a menu is open. It's lost when the page reloads, and that's fine for a menu. Some state is shared by several components on the page, such as the products you've picked to compare. It also lives in the page's memory, so a reload loses it.
Other places last longer. The page's address, its URL, can hold state. Google Maps writes the map's position and zoom into the address, and a YouTube link ending in &t=90s starts the video at one minute thirty. That state survives a reload and works as a link you send to someone. The browser's storage on the device keeps state such as a dark mode setting or an unsent draft, on that device only. And the server keeps state with the person's account, so it follows them to every device, as the lesson Where data lives explained.
Frameworks give developers tools for each place, but they don't choose. Where each piece of state lives is a decision about what visitors expect, so it belongs in the brief.
Swipe sideways to see the whole figure.
Cheat sheet
- Stateétat
- the data that a page keeps in one place, such as the number of passengers, from which the screen is drawn.
- URLURL, adresse web
- the full address of a page, such as https://www.sncf-connect.com/app/home/search.
- Local storagestockage local
- a place in the browser where a page keeps small things, such as a dark mode choice, on this device only.
- Routerrouteur
- the part of a framework that links each address to a screen, and can keep state in the address.
The same feature in plain JavaScript and in React
Plain JavaScript changes each part of the page by hand, while React describes the screen once and redraws it.
The feature in the example below is a message box with a limit of 280 characters. A counter shows how many characters you've typed, and the Send button turns off when you go over the limit.
On the left, plain JavaScript. The line with addEventListener("input", …) tells the browser to run some code each time a key changes the text. Inside, const n = message.value.length counts the characters. Then count.textContent = … writes the new count into the counter, and send.disabled = n > 280 switches the button off or on. Each part of the page that shows the data is updated by hand. With two displays that's easy. With twenty, one gets forgotten.
On the right, React. function Message() defines a component called Message. The line with useState("") creates the state: the text, empty at first, and setText, the only way to change it. Then return ( … ) describes the screen with tags that look like HTML, which React developers call JSX. Inside them, {text.length} inserts a value from the state, and disabled={text.length > 280} decides the button's state. onChange calls setText at each key. Nothing updates the counter or the button directly: React redraws them from the state.
Plain JavaScript
<textarea id="message"></textarea>
<p id="count">0 / 280</p>
<button id="send">Send</button>message.addEventListener("input", () => {
const n = message.value.length;
count.textContent = n + " / 280";
send.disabled = n > 280;
});React
import { useState } from "react";
function Message() {
const [text, setText] = useState("");
return (
<>
<textarea value={text}
onChange={(e) => setText(e.target.value)} />
<p>{text.length} / 280</p>
<button disabled={text.length > 280}>Send</button>
</>
);
}Cheat sheet
- ReactReact
- a popular JavaScript tool that builds only the part of a site that runs in the browser.
- addEventListeneraddEventListener
- the JavaScript instruction that creates an event listener, as in
button.addEventListener("click", …). - textContenttextContent
- the JavaScript instruction that sets the text of an element, shown exactly as written, even if it contains tags.
- useStateuseState
- the React instruction that creates a piece of state and the only function allowed to change it.
- JSXJSX
- the way React components describe the screen, with tags that look like HTML mixed into the JavaScript.
The same feature in Vue and in Svelte
Vue and Svelte write the same component closer to plain HTML, each with a few words of its own.
The example below is the same message box, written in Vue and in Svelte. The three ideas are the same: a component, a piece of state, and a screen redrawn from it. Only the spelling changes.
On the left, Vue. A Vue component has a script part and a template part. In the script, ref("") creates the state: the text, empty at first. The template is plain HTML with a few additions. v-model="text" links the box and the state in both directions: typing changes the state, and changing the state changes the box. {{ text.length }} inserts a value from the state. And the colon in :disabled means "work this out from the state".
On the right, Svelte, the shortest of the four. $state("") creates the state, bind:value links the box to it, and {text.length} inserts a value. Svelte is a compiler: before the site goes online, it turns this code into plain JavaScript, so the browser doesn't download a framework at all, and the files are smaller. Whatever the framework, you can find the state by its word: useState in React, ref in Vue, $state in Svelte.
Vue
<script setup>
import { ref } from "vue";
const text = ref("");
</script>
<template>
<textarea v-model="text"></textarea>
<p>{{ text.length }} / 280</p>
<button :disabled="text.length > 280">Send</button>
</template>Svelte
<script>
let text = $state("");
</script>
<textarea bind:value={text}></textarea>
<p>{text.length} / 280</p>
<button disabled={text.length > 280}>Send</button>Cheat sheet
- VueVue.js
- a framework for building interfaces from components, created by Evan You and maintained by an independent team.
- SvelteSvelte
- a framework that turns its components into plain JavaScript before the site goes online, so it sends less code.
- Templategabarit, template
- a page layout with empty places that a program fills with data, such as a name or a price.
- Compilercompilateur
- a program that turns code written by developers into another form, such as plain JavaScript that browsers run.
Reading a framework project
You won't write this code, but you'll see it, in a pull request or in an agent's chat. Three clues tell you what a project is built with.
The first is a file called package.json at the top of the project. It's the project's shopping list: every package it uses, with its version, such as "react": "19.1.0", or "vue", "svelte" or "@angular/core". The second is the end of the files' names. Files ending in .jsx or .tsx are usually React, .vue files are Vue, .svelte files are Svelte, and files ending in .component.ts are Angular. The letters ts mean TypeScript, JavaScript with labels that say what kind of data each value holds. The third is a folder called components, with one file per piece: Header, RecipeCard, Stars. When those names match the components in the design, that's a good sign.
That's enough to ask a precise question: "Which version of the framework is this, and is it still supported?"
Cheat sheet
- package.jsonpackage.json
- the file at the top of a JavaScript project that lists every package it uses, with its version.
- Dependencydépendance
- code written by other people that a project uses, and that must be updated regularly.
- TypeScriptTypeScript
- JavaScript with labels that say what kind of data each value holds, so that more mistakes are caught early.
- Pull requestpull request, demande de fusion
- a change proposed for review before it joins the live site, with the list of what changed.
What to ask
These questions work with a developer, an agency, or an AI agent's plan.
Ask for the list of components and where each one is used. If the same piece appears copied in many places, ask why it isn't one component. Ask where each piece of state is kept (the page's memory, the address, the device or the server) and how long it lasts. The right answer depends on what visitors expect to find again, so say what you expect.
Ask which framework and which version the project uses, and why that one: the package.json file answers the first part in a second. And ask whether the design files and the code use the same list of components, so that a change in one has an obvious place in the other.
Cheat sheet
- Componentcomposant
- a reusable piece of a page, such as a button or a card, designed once and used everywhere.
- Stateétat
- the data that a page keeps in one place, such as the number of passengers, from which the screen is drawn.
- Versionversion
- one numbered release of a package or a tool, such as 5.2.1, where higher numbers are newer.
- FigmaFigma
- the online design tool that most designers use to draw mockups and components.
Practise this strand
These questions put you in the situations this lesson describes. You answer in your own words, and you get a level, feedback and a full answer.