Props and state

Treat props as read-only

Ask the parent to provide a new value instead of mutating an input inside the child.

Props are read-only snapshots. A child must not assign to them or mutate an object received through them.

This breaks one-way data flow:

function Task({ task }) {
  task.done = true
  return <p>{task.title}</p>
}

The object belongs to the parent. Mutating it changes data from an earlier render without asking the owner to update.

When the child needs a change, pass an event callback:

function Task({ task, onToggle }) {
  return (
    <label>
      <input
        type="checkbox"
        checked={task.done}
        onChange={() => onToggle(task.id)}
      />
      {task.title}
    </label>
  )
}

The child reports the event. The parent updates its state and passes a new task prop on the next render.

Avoid copying a prop into state by default:

const [name, setName] = useState(user.name)

Later prop changes will not automatically replace that state. This is correct only when name is an intentional editable draft. Otherwise calculate from the prop directly.

Freeze a prop object during development and try the mutation example. The failure makes the ownership mistake easier to see.

Lesson completed

Take this course offline

Get every free book, course edition, and software download.

Get the download library →