liveBook · Manning

Component re-rendering

As explained in React Quickly, Second Edition

Component re-rendering is the repeated execution of a component's rendering logic to produce updated user-interface output.

Click a counter’s Increment button and its displayed value changes. The state setter updates the value, then React runs the component’s rendering logic again to produce the new output. Clicking Reset when the value is already 0 is different: with useState, setting the same value does not cause a re-render. section 5.2.5

A functional component renders when:

  • It mounts—appearing in the component tree for the first time. section 6.2
  • Its parent renders. A child can run again even when its props have not changed. section 6.2.2
  • A stateful hook updates its value. React may batch nearby triggers, so do not rely on a particular number of renders. section 6.2 section 6.2.3

A to-do button that does nothing

Mutating an array with `todos.splice(index, 1)` and then calling `setTodos(todos)` passes the same array back to the setter; the list does not re-render. Instead, create an array without that item: `setTodos(value => [...value.slice(0, index), ...value.slice(index + 1)])`. The new state value lets React render the updated list. section 5.2.5

Listing 5.7 A proper to-do list application
import { useState } from "react";
function TodoApplication({ initialList }) {
  const [todos, setTodos] = useState(initialList);
  return (
    <main>
      {todos.map((todo, index) => (
        <p key={todo}>
          {todo}
          <button
            onClick={() => {
              setTodos((value) => [         #1
                ...value.slice(0, index),   #1
                ...value.slice(index + 1),  #1
              ]);
            }}
          >
            x
          </button>
        </p>
      ))}
    </main>
  );
}
function App() {
  const items = ["Feed the plants", "Water the dishes", "Clean the cat"];
  return <TodoApplication initialList={items} />;
}
export default App;

See the working removal handler create a new array before updating state. section 5.2.5

Keep rapidly changing details out of state when the UI only needs a simpler answer. For a background that changes when the pointer crosses the middle, storing every pointer position causes repeated renders; storing only which side the pointer is on renders when that answer changes. React Developer Tools can highlight components as they render when you need to check what is happening. section 6.2.3 section 5.2.5

Do not assume rendering repeats initialization. A class constructor runs once, even though `render` can run again; an ID created inside `render` would be regenerated. Also note the class-state difference: calling `setState` re-renders a class component even with unchanged values, unlike setting an unchanged value through useState. section 4.4.4 section 5.3.2

How React Quickly, Second Edition covers it

How deep it goes
Identifies mount, parent render, and stateful-hook updates as triggers, then examines batching, unchanged state, and excessive rendering.
Examples
Uses a resettable counter, a broken and repaired to-do list, a parent-rendered child, and a pointer-sensitive background.
What it assumes
Builds on components, props, and state setters while defining the render triggers rather than assuming prior knowledge of the component life cycle.
What you can do after
Diagnose/debug with React Developer Tools and choose state values that produce needed updates without needless renders.
How it connects
Connects re-rendering to useState, parent components, props, class constructors, setState, and the component life cycle.

Also explained in

Compare how 3 books explain component re-rendering →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of React Quickly, Second Edition. The section links point to the parts of the book it draws on.