Until now the products came from src/data.js, a file inside the page. Now they live in the shop's API: the page asks GET /api/products, and the answer arrives a moment later. React never waits for it. It draws the page right away with what it has, so the products must be kept in state, starting as an empty array.
Asking the API is not part of drawing the page, so it goes in an effect. With [] as its dependencies, the effect runs once, after the first draw. The effect's own function can't be async, so the waiting happens in an async function written inside it and called right away. When the answer is in, the state setter makes React draw again. Here is the idea for the categories:
const [categories, setCategories] = useState([]);
useEffect(() => {
async function loadCategories() {
const response = await fetch("/api/categories");
setCategories(await response.json());
}
loadCategories();
}, []);
The check opens the page, prints the screen while the request waits, then what changes when the answer arrives, then clicks "Add to cart" on the Mug:
> open the page
request: GET /api/products ...
screen while waiting:
text: Cart (0)
section "Products"
text: 0 products
list (empty)
answer: GET /api/products -> 200
screen changes:
- text: 0 products
+ text: 8 products
+ item: Mug $12
+ item: Notebook $7 Out of stock
…
> click "Add to cart" in "Mug"
- text: Cart (0)
+ text: Cart (1)
+ item: Mug × 1 $12
Your task: in src/App.jsx, keep the products in state (starting as []), show them with a ProductList, and add an effect with [] whose async function loadProducts awaits fetch("/api/products"), reads the JSON and gives it to setProducts.
Assignment
Follow the Coding Tutorial to load the shop's products from /api/products in an effect and show them in the page.
Hint
If the check prints no request, the effect never calls loadProducts(). If the request answers 200 but the page still says 0 products, the data never reached setProducts.
Free plan: 30 tutor messages. PRO is unlimited.
