liveBook · Manning

React rendering

As explained in React in Depth

React rendering is the process by which React evaluates components and produces their user-interface output.

React rendering evaluates components and produces their user-interface output. A functional component renders when mounted, when its parent re-renders, or when a hook flags it for re-render. React may batch multiple causes, so one state change and a parent render can result in one render or two. section 3.1

Use these rules when reasoning about rendering behavior:

  • Do not treat changed properties as the only render trigger; parent renders and hook behavior also matter. section 3.0 section 3.1
  • Expect child components to render when their parent renders, even when children are self-contained or receive unchanged properties. section 3.2.1
  • Use memo() when a component can reuse the same result for identical properties; avoid optimization that adds complexity without measurable benefit. section 3.0 section 3.2.1
  • Distinguish a missing dependency array, which runs an effect on every render, from an empty array, which runs it only on initial mounting. section 3.3.2

Controlled to-do input

A to-do component stores the item list and the current input value with useState. Typing updates the input state and repeatedly renders the component and its Items child. Wrapping Items with memo() lets React reuse its result while its items property remains unchanged, reducing work during typing. section 3.2.1

Listing 3.5 A to-do list without memoization
import { useState } from "react";
function Items({ items }) {     #1
  return (
    <>
      <h2>Todo items</h2>
      <ul>
        {items.map((todo) => (
          <li key={todo}>{todo}</li>
        ))}
      </ul>
    </>
  );
}
function Todo() {
  const [items, setItems] = useState(["Clean gutter", "Do dishes"]);
  const [newItem, setNewItem] = useState("");
  const onSubmit = (evt) => {
    setItems((items) => items.concat([newItem]));
    setNewItem("");
    evt.preventDefault();
  };
  const onChange =  #2
    (evt) => setNewItem(evt.target.value);    #2
  return (
    <main>
      <Items items={items} />     #3
      <form onSubmit={onSubmit}>
        <input value={newItem} onChange={onChange} />
        <button>Add</button>
      </form>
    </main>
  );
}
function App() {
  return <Todo />;
}
export default App;

Inspect the runnable to-do implementation without memoization, including controlled input state, item rendering, and the parent-child relationship. section 3.2.1

How React in Depth covers it

How deep it goes
Defines render triggers, batching, child behavior, memoization, and dependency-array timing without detailing React internals.
Examples
Uses controlled to-do lists, browser performance measurements, memoized Items components, and effect-based render tracking.
What it assumes
Assumes React fundamentals and controlled inputs while clarifying common rendering misconceptions.
What you can do after
Diagnose/debug with it by identifying render triggers and applying memo() or dependency-array choices to reduce unnecessary work.
How it connects
Connects component rendering to state changes, parent rendering, hooks, memoization, dependency arrays, reconciliation, and the DOM.

Related concepts

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