Jamie Balfour

Welcome to my personal website.

Find out more about me, my personal projects, reviews, courses and much more here.

Part 4.4Sharing state between components

Choose the owner

When sibling components need the same changing data, move that state to their closest common parent. The parent passes values down as props and passes handlers down so children can request changes. This creates one source of truth.

JSX
function App() {
  const [tasks, setTasks] = useState(initialTasks);
  return <>
    <TaskForm onAdd={handleAdd} />
    <TaskList tasks={tasks} onToggle={handleToggle} />
  </>;
}

Derive rather than duplicate

Do not store a value that can be calculated cheaply from existing props or state. Calculate const remaining = tasks.filter(task => !task.complete).length during rendering. Duplicated state can fall out of sync.

State follows position

React associates state with a component's type and position in the rendered tree. Changing its key gives it a new identity and resets its state. Use that deliberately, not as a general way to force updates.

Trace one update

When TaskForm calls onAdd, it is calling the function supplied by App. That function updates the tasks owned by App. React renders App again, calculates a new remaining count and gives TaskList the new array. The child never edits the parent's array directly.

Put state as low as possible but high enough for every component that needs it. Moving all state to the top makes components unnecessarily coupled; leaving shared state in one child makes siblings disagree.

Challenge: add a task filter

Add filter state to App with values all, active and complete. Pass the current filter and an onFilterChange handler to a TaskFilters component. Derive the visible tasks during rendering rather than storing a second task array.

Success criteria
  • Changing the filter does not modify the tasks.
  • The summary still uses all tasks.
  • Adding or toggling a task immediately updates the filtered list.
Feedback 👍
Comments are sent via email to me.