Level 4 · Full-Stack Application Development · Course 4.1 React Fundamentals

Module 33: State and Events

Goal: make your React app interactive: remember changing data with state, respond to events, control form inputs, and share state between components.

You'll need: your enquiries project from Module 32.

Lessons

  1. 1State with useState15–25 minutes✓
  2. 2Events15–25 minutes✓
  3. 3Updating state correctly15–25 minutes✓
  4. 4Controlled inputs15–25 minutes✓
  5. 5Lifting state up15–25 minutes✓

🛠️Module practice: an interactive enquiry dashboard

  1. Enquiries kept in state in Dashboard.
  2. Mark an enquiry as in progress or closed, with immutable updates.
  3. Search and status filter as controlled inputs, with a Clear button.
  4. A Summary that always matches the lists.
  5. No state that can be calculated from other state. Commit.

✅Module check

Explain in a few sentences, in your own words:

What is state in React, how should it be updated, and where should it live?

Show a good answer

A good answer mentions: state is data a component remembers that can change; changing it with its setter makes React re-render the screen. Updates must create new arrays or objects (never change the existing ones), use updater functions when the new value depends on the old, and state should be kept minimal, with anything derivable calculated while rendering. Inputs are controlled by state. Shared state is lifted to the closest common parent and passed down as props, with changes sent up through callback props.

📝Module quiz

10 questions · 10 marks each · 100 marks in all · pass mark 70% · retry as often as you like ·

1. You change a normal variable in a click handler but the screen doesn't update. Why?

Why each option is right or wrong

  • “The click handler needs to be marked as async first” (Incorrect): async is for waiting on promises; it doesn't make React re-render.
  • “Variables in React can only hold text, not numbers” (Incorrect): Variables can hold anything; the issue is that React isn't notified.
  • “The browser caches the page and needs a refresh to update” (Incorrect): Refreshing would reset everything. React updates the screen when state changes.
  • “Only state changes through the setter make React re-render” is correct.

    React redraws a component when its state changes through the setter function from useState. A normal variable can change, but React isn't told, so the screen keeps showing the old value. It's also reset each time the component renders.

    • Fix: const [count, setCount] = useState(0), then setCount(count + 1).
    • Normal variables: fine for values worked out during rendering.

📖 Revise: Lesson 1: State with useState

Question ID module-33-q1 · Report a mistake in this question
2. What does useState(0) return?

Why each option is right or wrong

  • “The number 0, which you can change directly like any variable” (Incorrect): It returns a pair, and changing the value directly wouldn't re-render.
  • “A new component that displays the value on screen” (Incorrect): useState returns data and a setter, not a component.
  • “A promise that resolves to the starting value later” (Incorrect): useState is synchronous; there's no promise.
  • “A pair: the current value and a function to change it” is correct.

    useState gives back an array of two items, usually unpacked as const [count, setCount] = useState(0). The 0 is the starting value, used only on the first render.

    • Naming: thing and setThing.
    • Starting value: used once; later renders keep the current value.

📖 Revise: Lesson 1: State with useState

Question ID module-33-q2 · Report a mistake in this question
3. What's wrong with onClick={save()}?

Why each option is right or wrong

  • “Nothing; brackets are needed so React knows it's a function” (Incorrect): React needs the function itself. Brackets call it right away.
  • “onClick only works on buttons, not other elements” (Incorrect): onClick works on most elements; the brackets are the problem.
  • “It should be written onclick in lower case, as in HTML” (Incorrect): JSX uses camelCase onClick; the brackets are the real bug.
  • “It calls save during rendering instead of on click” is correct.

    The brackets run save immediately while React is drawing the component, and its result is passed as the handler. Pass the function itself, onClick={save}, or wrap it: onClick={() => save(id)}.

    • Symptom: it runs on page load, and can cause an endless loop if it sets state.
    • With arguments: use an arrow function.

📖 Revise: Lesson 2: Events

Question ID module-33-q3 · Report a mistake in this question
4. list.push(item); setList(list); doesn't update the screen. Why?

Why each option is right or wrong

  • “push doesn't work on arrays stored in state” (Incorrect): push works, but it changes the array in place, which React doesn't detect.
  • “The setter needs to be called twice to update” (Incorrect): Calling it twice with the same array still shows no change.
  • “Arrays can't be stored in state, only single values” (Incorrect): State can hold arrays and objects; just replace them with new ones.
  • “It's the same array, so React sees no change” is correct.

    push changes the existing array. Passing the same array to the setter looks like no change, because React compares by identity, so it may skip the re-render. Create a new array instead: setList([...list, item]).

    • Rule: don't change state in place; replace it with a new copy.
    • Objects too: setForm({ ...form, name }).

📖 Revise: Lesson 3: Updating state correctly

Question ID module-33-q4 · Report a mistake in this question
5. Should you store both enquiries and openEnquiries in state?

Why each option is right or wrong

  • “Yes, storing both is faster than filtering on every render” (Incorrect): Filtering a normal-sized list is quick, and storing both risks them disagreeing.
  • “Yes, React needs a separate piece of state for each list it shows” (Incorrect): React can show any value, including calculated ones.
  • “No, store only openEnquiries and delete the closed ones” (Incorrect): Then the closed enquiries would be lost.
  • “No, store enquiries and calculate the open ones while rendering” is correct.

    openEnquiries can be worked out from enquiries with a filter. Storing both means keeping them in sync by hand, and they'll eventually disagree. Calculating it on each render keeps one source of truth.

    • Derived data: calculate it, don't store it.
    • Example: const open = enquiries.filter(e => e.status === "open").

📖 Revise: Lesson 3: Updating state correctly

Question ID module-33-q5 · Report a mistake in this question
6. In a controlled input, where does the displayed value come from?

Why each option is right or wrong

  • “From the browser, which stores what was last typed” (Incorrect): In a controlled input React supplies the value; the browser just displays it.
  • “From the placeholder attribute set on the input” (Incorrect): The placeholder is hint text, not the value.
  • “From the server, which sends it on every keystroke” (Incorrect): Typing updates local state; no server is involved.
  • “From state, updated on every change” is correct.

    A controlled input has value={name} and onChange={e => setName(e.target.value)}. Each keystroke updates state, and the input shows whatever state holds, so React is the single source of truth.

    • Benefit: you can validate, format or clear the field from code.
    • Forget onChange and the field won't accept typing.

📖 Revise: Lesson 4: Controlled inputs

Question ID module-33-q6 · Report a mistake in this question
7. Two sibling components need the same data. Where should the state live?

Why each option is right or wrong

  • “In each sibling, copied and kept in sync with an effect” (Incorrect): Two copies easily drift apart. One shared copy in the parent is simpler.
  • “In a global variable at the top of the file” (Incorrect): React doesn't re-render when a normal variable changes.
  • “In the browser's local storage, read by each sibling” (Incorrect): Local storage is for saving between visits, not sharing live state.
  • “In their closest common parent, passed down as props” is correct.

    Siblings can't read each other's state. Moving the state up to the nearest parent that contains both, and passing it down, keeps them in step. This is called lifting state up.

    • Example: a filter bar and a list both inside the dashboard page.
    • Many levels deep? Context can help later.

📖 Revise: Lesson 5: Lifting state up

Question ID module-33-q7 · Report a mistake in this question
8. How does a child component change state that lives in its parent?

Why each option is right or wrong

  • “By changing the props it received from the parent” (Incorrect): Props are read-only; changing them doesn't update the parent.
  • “By importing the parent's state variable directly” (Incorrect): State lives inside a component; it can't be imported.
  • “Children can't affect their parent's state in any way” (Incorrect): They can, by calling a function prop.
  • “By calling a function the parent passed down as a prop” is correct.

    The parent passes a function such as onSelect={setSelected} or a handler that calls it. The child calls onSelect(id) and the parent's state changes, which re-renders both.

    • Data flows down; events flow up.
    • Naming: on… props for these functions.

📖 Revise: Lesson 5: Lifting state up

Question ID module-33-q8 · Report a mistake in this question
9. Why name a prop onClose and the function passed to it handleClose?

Why each option is right or wrong

  • “React only passes functions whose names start with handle” (Incorrect): React accepts any function name; the naming is just a convention.
  • “Props starting with on run automatically when the page loads” (Incorrect): on… props run only when the child calls them.
  • “The names must match the HTML attributes of the element” (Incorrect): These are your own prop names, not HTML attributes.
  • “A common convention: on… for the prop, handle… for the function” is correct.

    onClose says "call this when closing happens", like onClick. handleClose says "this is the function that handles closing". Following the convention makes code easier for others, and AI tools, to read.

    • It's a convention, not a rule: React doesn't require it.
    • Example: <Modal onClose={handleClose} />.

📖 Revise: Lesson 2: Events

Question ID module-33-q9 · Report a mistake in this question
10. How do you clear a controlled input from a button?

Why each option is right or wrong

  • “Reload the page so every input is empty again” (Incorrect): Reloading loses everything else too. Setting state clears just that field.
  • “Delete the input element and add a new one” (Incorrect): React updates inputs from state; there's no need to replace them.
  • “Change the input's placeholder to an empty string” (Incorrect): The placeholder is hint text; it doesn't clear the value.
  • “Set its state back to an empty string” is correct.

    Because a controlled input shows whatever state holds, setName("") empties it. There's no need to reach into the page and change the input yourself.

    • Clearing a form: reset the whole form object to its starting values.
    • Plus: a ref can then move focus back to the first field.

📖 Revise: Lesson 4: Controlled inputs

Question ID module-33-q10 · Report a mistake in this question

ProLearners Assist