A checkbox and a select are controlled like the search field: state holds what they show, and onChange updates it. There are two differences. A checkbox is on or off, so its state is true or false. It shows that state with checked, and event.target.checked gives you the new one. A select shows its state with value, and each option has a value that goes into state when it is picked.
A label gives a field its name: its htmlFor (JSX's word for for) matches the field's id. For example, a gift-wrap box on a checkout page:
const [giftWrap, setGiftWrap] = useState(false);
<input id="gift" type="checkbox" checked={giftWrap}
onChange={(event) => setGiftWrap(event.target.checked)}
/>
<label htmlFor="gift">Gift wrap</label>
The list is then computed from the state during the draw. The filter leaves out products whose stock is 0 when the box is on. Then shown, the new array filter made, is sorted by name or by price. sort changes the array it is called on, so sorting shown leaves the products prop alone.
The check must see:
> open the page
checkbox "In stock only": off
select "Sort by": "Name" of [Name, Price]
text: 8 products Gift card, Lamp, Mug, Notebook, …
> click "In stock only"
checkbox "In stock only": on
text: 7 products (Notebook is gone)
> choose "Price" in "Sort by"
select "Sort by": "Price" of [Name, Price]
Pen $2, Stapler $9, Mug $12, Plant $15, Teapot $22, Lamp $29, Gift card $50
Your task: in src/ProductList.jsx, add an In stock only checkbox and a Sort by select with the options Name and Price, each with its own state and label, and make the list follow them.
Assignment
Follow the Coding Tutorial to add the checkbox and the select to src/ProductList.jsx, then filter and sort the list from their state.
Hint
For the price sort, a.price - b.price is negative when a is cheaper, which puts it first. For names, a.name.localeCompare(b.name) does the same job.
Free plan: 30 tutor messages. PRO is unlimited.
