Components and JSX

Keep rendering pure

Make component output depend only on props, state, and context without changing outside values during render.

Rendering must be a calculation, not an operation on the outside world.

Given the same props, state, and context, a component should return the same JSX. This lets React pause, restart, or repeat rendering safely.

This component is impure:

let nextId = 0

function Task() {
  nextId += 1
  return <p>Task {nextId}</p>
}

Every render changes a value outside the component. Rendering twice produces different output, and separate component instances affect each other.

Do not mutate props, write storage, start timers, send requests, or change the DOM while rendering.

Put work where its cause belongs:

  • A click-caused request belongs in the click handler.
  • A value derived from props belongs in the render calculation.
  • Synchronization with an external system belongs in an Effect.

Local mutation is fine when the value was created during this render:

const rows = []

for (const task of tasks) {
  rows.push(<li key={task.id}>{task.title}</li>)
}

The new rows array does not affect an earlier render or another component.

Strict Mode intentionally repeats some development work to reveal impurities. If a repeated render creates duplicate data or requests, fix where that side effect occurs rather than disabling the check.

Add a console.log to a component and observe renders. Then verify that repeating the component call does not change application data.

Lesson completed

Take this course offline

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

Get the download library →