An accordion is a list of questions where clicking a question shows its answer. In this one, only one answer is open at a time: opening another question closes the first, and clicking the open question closes it.
You don't need a true or false for every question. One state variable is enough: the id of the open question, or null when none is open. Each answer is hidden unless its question's id is that id, so opening a new one closes the old one by itself.
Two attributes make it work for screen readers too. aria-expanded on a button says whether what it opens is open (the check prints it as "expanded" or "collapsed"), and aria-controls names the id of the part it opens. Here is a single show/hide button that uses a true or false:
const [showInfo, setShowInfo] = useState(false);
<button aria-expanded={showInfo} onClick={() => setShowInfo(!showInfo)}>
Shipping info
</button>
<p hidden={!showInfo}>We ship every weekday.</p>
The check opens the page, clicks the delivery question, then clicks the returns question twice. Your page must print:
> open the page
screen:
main
heading 1: Frequently asked questions
button: How long does delivery take? (collapsed)
button: Is delivery free? (collapsed)
button: Can I return a product? (collapsed)
> click "How long does delivery take?"
screen changes:
main
- button: How long does delivery take? (collapsed)
+ button: How long does delivery take? (expanded)
+ text: Orders leave the shop within 2 days.
> click "Can I return a product?"
screen changes:
main
- button: How long does delivery take? (expanded)
- text: Orders leave the shop within 2 days.
+ button: How long does delivery take? (collapsed)
- button: Can I return a product? (collapsed)
+ button: Can I return a product? (expanded)
+ text: Yes, within 30 days, unused and in its box.
> click "Can I return a product?"
screen changes:
main
- button: Can I return a product? (expanded)
- text: Yes, within 30 days, unused and in its box.
+ button: Can I return a product? (collapsed)
Your task: in src/App.jsx, the questions and their answers are already on the page, all open. Add an openId state, hide every answer but the open one, write a toggle(id) function and call it from each button, and give each button aria-controls and aria-expanded.
Assignment
Follow the Coding Tutorial to turn the always-open list of answers into an accordion with one open answer at a time.
Hinthidden={…} and aria-expanded={…} both take a true or false: compare openId with faq.id. In toggle, a ternary picks null when the clicked id is already the open one.
Free plan: 30 tutor messages. PRO is unlimited.
