Theory
A UI that does nothing is not a UI
Last lesson's FestConnect components display events but sit there inertly. A real interface RESPONDS: click a card to select it, see 'Sold out' when seats hit zero, render the whole list from an array.
This lesson makes components react: events (handling clicks), lists (rendering an array of events), and conditional rendering (showing 'Sold out' only when appropriate). It uses React's class-component style, which your syllabus teaches alongside the modern function-and-hooks style (coming later). The concepts, events, lists, conditionals, are the same in both styles.
Theory
Handling events
React handles user actions with camelCase event handlers that take a FUNCTION:
<button onClick={handleClick}>Register</button>
Note onClick={handleClick}: you pass the function's NAME (a reference), NOT handleClick() (which would CALL it immediately on render). To pass an ARGUMENT, wrap it in an arrow function:
<button onClick={() => handleClick(eventId)}>Register</button>
The handler receives an event object (conventionally e) carrying details like e.target. This is the same event idea from BCA405-01's DOM, wrapped in React's syntax. The immediate-call bug (onClick={handleClick(id)}) is the most common React event mistake.
Practical
List with keys, events, and conditional rendering
function EventList() {
const events = [
{ id: 1, name: "Garba Night", seats: 350 },
{ id: 2, name: "Coding Contest", seats: 0 },
];
function handleClick(name) {
alert("Selected: " + name);
}
return (
<ul>
{events.map((ev) => (
<li key={ev.id}> {/* each item needs a KEY */}
{ev.name} -
{/* conditional rendering with a ternary */}
{ev.seats > 0
? <span> {ev.seats} seats</span>
: <span> Sold out</span>}
{/* arrow wrapper to pass an argument */}
<button onClick={() => handleClick(ev.name)}>Select</button>
</li>
))}
</ul>
);
}
This example runs in Gri-Learn on the web, where you can edit it and see the output.
Theory
Lists and conditional rendering
Lists: render an array by calling .map(), returning JSX for each item. Every rendered item needs a unique `key` prop (key={ev.id}): React uses keys to track which items changed, so it can update efficiently. A missing key produces a warning and can cause subtle bugs; use a stable unique id, not the array index where possible.
Conditional rendering: show content based on a condition, using:
- the ternary:
condition ? <A/> : <B/>(shows A or B) - logical AND:
condition && <A/>(shows A only if condition is true)
So ev.seats > 0 ? <span>{ev.seats} seats</span> : <span>Sold out</span> shows the seat count or 'Sold out'. These are ordinary JavaScript operators used inside JSX's {}.
Quiz
You write <button onClick={handleClick(id)}>Go</button> to pass id to the handler. What actually happens?
- It correctly calls handleClick(id) when the button is clicked
- handleClick(id) is called IMMEDIATELY when the component renders, not on click; you need an arrow wrapper onClick={() => handleClick(id)}
- It throws a syntax error
- The id is ignored
Show the answer
handleClick(id) is called IMMEDIATELY when the component renders, not on click; you need an arrow wrapper onClick={() => handleClick(id)}
onClick={handleClick(id)} CALLS handleClick(id) right away during render (its RETURN value becomes the click handler), so it fires immediately and not on click: a classic React bug. To pass an argument on click, wrap it in an arrow function: onClick={() => handleClick(id)}, which gives onClick a FUNCTION that calls handleClick(id) only when clicked. Option A is what you INTENDED but not what this code does. Option C is wrong: it is valid syntax, just wrong behaviour (which makes it insidious). Option D misses that the whole call runs early. Rule: onClick needs a function reference; to pass arguments, use an arrow wrapper.
Think first
Why does every list item need a key?
React warns if you map a list to JSX without a key prop. What does the key do, and why does it matter for performance and correctness? Then tap.
Show the answer
The KEY gives each list item a stable IDENTITY so React can track it across re-renders. When the list changes (an item added, removed, or reordered), React compares the new list to the old by KEY to figure out the MINIMAL update: which items to keep, move, or replace, instead of rebuilding everything. Without keys, React falls back to position, which can cause it to update the WRONG items (e.g. an input's text sticking to the wrong row) and do more work than needed. Use a STABLE UNIQUE id (like ev.id), not the array index, because indexes shift when items are added/removed. The key is not shown to the user; it is React's internal handle on each item. Missing or unstable keys cause both the warning and real, confusing bugs.
Watch out
Events, lists, conditionals traps
Immediate-call handler: onClick={fn(arg)} runs now; use onClick={() => fn(arg)}.
Missing key on mapped items: causes a warning and update bugs; use a stable unique id.
Using array index as key when items reorder: indexes shift; prefer a real id.
Confusing = and =>: handlers pass a function, often an arrow.
Forgetting {} around JS in JSX: conditionals and map go inside curly braces.
Theory
It reacts; now capture input
FestConnect's list now responds to clicks, renders from an array with keys, and shows 'Sold out' conditionally. The next big interaction is INPUT: forms where users type their registration details. React handles forms in a specific way, controlled components, where the form's data lives in the component and every keystroke updates it. Forms, controlled inputs, and select/textarea come next, then hooks complete the modern React picture.
Summary
Key takeaways
- React components react to users; class components (extending React.Component with render()) are the older style, alongside function components + hooks.
- Events use camelCase handlers taking a function: onClick={handleClick}; the handler gets an event object (e).
- To pass an argument, use an arrow wrapper: onClick={() => handleClick(id)}; onClick={handleClick(id)} calls it immediately (bug).
- Render lists with .map() returning JSX per item; each needs a unique key prop (use a stable id, not the index).
- Keys give items identity so React updates efficiently and correctly.
- Conditional rendering: ternary (cond ? <A/> : <B/>) or logical AND (cond && <A/>).
- Memory hook: arrow-wrap for arguments, key every list item, ternary/&& for conditionals.