Module 1: React Foundations
Why React and How It Thinks
React is a JavaScript library for building user interfaces. It was created at Facebook (now Meta) and released as open source in 2013, and today it is one of the most widely used tools for building web frontends. Before you write any React code, it pays to understand the way React thinks, because almost every beginner mistake comes from treating React like plain JavaScript that edits the page directly.
The problem React solves
Imagine you are building a small shop page for a Nairobi electronics store. When a customer clicks "Add to cart", several things must change at once: the cart badge in the header, the button text, the total price and perhaps a "low stock" warning. With plain JavaScript you would find each element with document.querySelector and update it by hand. That works for one button. With fifty interactive pieces, you start forgetting to update something, and the page shows information that no longer matches your data.
React's answer is simple: you describe what the screen should look like for any given data, and React works out how to update the page. You stop writing instructions such as "find the badge and change its text to 3". Instead you write "the badge shows cart.length". When the data changes, React re-runs your description and updates only the parts of the page that actually changed.
UI as a function of state
The central idea is often written as UI = f(state). Your interface is the output of a function, and the input is your data, which React calls state. If you know the state, you know exactly what the screen shows. This makes interfaces predictable: there is one source of truth, and the page is always derived from it.
function CartBadge({ count }) {
return <span className="badge">{count} items</span>;
}
This is a component: a JavaScript function that receives data and returns a description of some UI. Notice there is no code that searches the page or edits it. If count becomes 4, React calls the function again and updates the text.
Declarative versus imperative
Plain DOM code is imperative: you give step-by-step commands. React code is declarative: you declare the result you want. Compare the two approaches for showing a message when a list is empty.
| Imperative (plain DOM) | Declarative (React) |
|---|---|
| Check the array, create a paragraph, set its text, append it, and remember to remove it when items are added. | Return {items.length === 0 && <p>No items yet</p>} and let React add or remove it. |
The declarative version cannot "forget" to remove the message, because the message only exists when the condition is true.
Components, re-rendering and the virtual DOM
A React app is a tree of components. A ShopPage might contain a Header, a ProductList and a Footer, and the ProductList contains many ProductCard components. When state changes in a component, React re-renders it: it calls the component function again, along with its children, to get a fresh description of the UI.
Calling functions is cheap, but touching the real page (the DOM) is comparatively slow. So React compares the new description with the previous one and applies only the differences to the real DOM. This comparison step is called reconciliation, and the in-memory description is often called the virtual DOM. You rarely need to think about it, but it explains why re-rendering is normal and not something to fear.
A worked example
Here is a tiny but complete React component that counts how many times a button is clicked:
import { useState } from "react";
export default function LikeButton() {
const [likes, setLikes] = useState(0);
return (
<button onClick={() => setLikes(likes + 1)}>
Like ({likes})
</button>
);
}
Read it in plain English: "This component has a piece of state called likes, starting at 0. It shows a button with the current number. When clicked, set likes to one more." You never touch the button's text directly. Calling setLikes tells React the state changed, React re-runs LikeButton, and the new number appears.
Where React fits
React handles the view layer. It does not include a router, a data-fetching library or a build tool. In practice you combine it with tools such as Vite (to create and build the project) and React Router (for pages), which you will use in this course. Frameworks such as Next.js build on React and add server rendering and routing, but they all share the same component model you are learning here.
Common mistakes to avoid
- Editing the DOM directly with
document.getElementByIdinside React components. Let state drive the UI instead. - Keeping the same information in two places, such as a cart array and a separate cart count. Derive the count from the array.
- Fearing re-renders. Re-rendering is how React works. Optimise only when you can measure a real problem.
- Changing variables that are not state and expecting the screen to update. Only state changes trigger a re-render.
Exercise
Open any shopping or banking website you use and pick one interactive area, such as a cart, a filter panel or a notification bell. Write down what data (state) that area depends on and what the screen shows for two different values of that state. Then sketch the area as a tree of three to six components with clear names.
Key points
- React lets you describe what the UI should look like for given data, and it updates the page for you.
- The core idea is UI = f(state): the screen is always derived from state.
- Components are functions that return UI descriptions, and re-rendering is normal.
- Never edit the DOM by hand inside React; change state instead.