Before React, here is what building an interface looked like. Suppose a page shows a shopping basket: a list of items, a count in the header, a total at the bottom, and a checkout button that is disabled when the basket is empty.
Now the user removes an item. Four things must change:
- Remove that row from the list.
- Decrease the count in the header.
- Recalculate the total.
- Possibly disable the checkout button.
In plain JavaScript you write all four, by hand:
row.remove();
document.querySelector("#count").textContent = items.length;
document.querySelector("#total").textContent = calculateTotal(items);
document.querySelector("#checkout").disabled = items.length === 0;
That works. Then a discount badge is added, and it too depends on the basket. Now every place that changes the basket must also update the badge — adding an item, removing one, changing a quantity, applying a coupon. Miss one, and the badge shows a discount for a basket that no longer qualifies.
Why this gets worse, not better
The trouble is that the work grows with places that change data multiplied by places that display it. Ten of each is a hundred paths to keep straight, and no compiler will tell you when one is missing. The bug is not in the code you wrote; it is in the code you did not write.
The result is a screen that disagrees with the data — a total that does not match the items, a button enabled when it should not be. Every experienced front-end developer has spent a day on one of these.
React's answer
Stop writing update steps. Instead, write one description of what the screen should look like for the current data:
function Basket({ items }) {
return (
<div>
<header>{items.length} items</header>
<ItemList items={items} />
<footer>Total: {calculateTotal(items)}</footer>
<button disabled={items.length === 0}>Checkout</button>
</div>
);
}
When the items change, React runs this again and updates whatever differs. There are no update paths to forget, because there are no update paths — the count, the total and the button are each described once, in terms of the data.
This is the whole idea, and it is worth stating as a sentence you will meet in every section of this course:
The screen is a function of state.
Give React the same data and you get the same screen, every time. Almost every React bug a beginner hits — a screen that will not update, a stale value in a handler, an effect that loops — is that principle being broken somewhere. Knowing it now is what stops the hooks later looking like arbitrary rules.