Explain how React calculates a screen update and preserves component identity.
Read the explanation, run the worked code, then complete the practice lab in Assignments. This advanced lesson includes worked code and a dedicated practice lab.
Understand the idea
The browser DOM is the live tree of elements, text nodes and properties that the browser uses to display a document. “Virtual DOM” is an informal name for React’s in-memory description of the desired UI. JSX creates React elements describing what should appear; it does not create a second hidden browser document. React also maintains internal bookkeeping for component state and scheduled work. You do not need to manipulate that internal structure directly.
Separate three events: a state update requests work, rendering calculates the next UI, and committing applies changes to the browser DOM. Browser layout and paint happen afterward as needed. Calling a component again does not mean replacing its entire HTML subtree. For example, changing a counter can update one text value while retaining the input next to it. The browser can preserve that input’s value because its node was reused.
Reconciliation is the process of matching the new description with the previously rendered tree. Element/component type and position matter; keys distinguish siblings when records move. This is not a generic search for the cheapest possible edit across every node in a document. Replacing one component type with another at a position discards the old subtree’s state. A stable key lets React associate a reordered row with the same record; changing a key deliberately asks for a new identity.
Use the first experiment below to separate component execution from DOM replacement. The input is intentionally uncontrolled so its current value belongs to the browser node. Type a draft and increase the counter. The draft stays even though App runs again. Reset input changes its key: the input remounts and returns to its default value. This is different from merely rerendering.
In the second experiment, each student row owns a note. With stable IDs, reversing the students keeps each note with the correct student. With index keys, the note stays at its position and can appear beside a different student. A key only has to be unique among siblings, but it must remain stable across renders. Random keys remount rows and lose local state.
Virtual DOM does not guarantee that every React app is faster than carefully written DOM code. Rendering, comparison and bookkeeping also cost work. Keep state close to where it is used, avoid unnecessary effects, and profile before adding memoization. memo and useMemo can reduce some repeated work but are not requirements for correct reconciliation. Modern React may pause, restart or discard render work, which is why rendering must remain pure; an attempted render is not proof that a commit happened.
Run the example
Use a separate React practice project with a Node.js version supported by Vite. Create it once with these commands, then use its development URL. Do not paste this into the Edupoly website’s own source files.
npm create vite@latest react-practice -- --template react
cd react-practice
npm install
npm run dev
Replace src/App.jsx with the following complete example. Keep Vite’s generated src/main.jsx entry point.
src/App.jsx
import { useState } from 'react';
export default function App() {
const [count, setCount] = useState(0);
const [inputVersion, setInputVersion] = useState(0);
return <main>
<h1>Count: {count}</h1>
<button onClick={() => setCount(n => n + 1)}>Increase count</button>
<label>Draft <input key={inputVersion} defaultValue="" /></label>
<button onClick={() => setInputVersion(n => n + 1)}>Reset input identity</button>
<p>Type a draft before increasing the count.</p>
</main>;
}
Expected result
Type “React practice”, then click Increase count three times: Count becomes 3 and the draft remains. Reset input identity clears the draft while the count stays 3. The reset comes from a changed key, not from an ordinary rerender.
Alternative worked example — replace src/App.jsx
import { useState } from 'react';
const initialStudents = [{id: 'asha', name: 'Asha'}, {id: 'ravi', name: 'Ravi'}];
function StudentRow({student}) {
const [note, setNote] = useState('');
return <li><label>{student.name}: <input value={note} onChange={e => setNote(e.target.value)} /></label></li>;
}
function Experiment({useIndex}) {
const [students, setStudents] = useState(initialStudents);
return <section>
<h2>{useIndex ? 'Index keys — compare the behavior' : 'Stable ID keys'}</h2>
<button onClick={() => setStudents(rows => [...rows].reverse())}>Reverse students</button>
<ul>{students.map((student, index) => <StudentRow key={useIndex ? index : student.id} student={student} />)}</ul>
</section>;
}
export default function App() {
return <main><Experiment useIndex={false} /><Experiment useIndex={true} /></main>;
}
Apply this to your assignments
Before running each experiment, predict whether the input or row state will survive. Repeat with your student-table, todo-delete and cart-reordering assignments: identify the record ID used as the key, edit a row, then sort, insert and delete other records. Record whether the edit remains attached to the correct record. Use the Assignments tab for the full lab and acceptance checks.
Practice starting point
Use the worked example above as your starting point.
Open Assignments for this lesson’s practice lab and acceptance checks.
Common mistakes
Do not say that every rerender updates every DOM node, that keys prevent rendering, or that a Virtual DOM is the Shadow DOM. Do not count development console logs as exact committed updates: Strict Mode may call render logic extra times. Never mutate the DOM owned by React to “help” its comparison. An index key is a poor choice when items can reorder, be inserted or be removed.
Check your understanding
- Predict the output before running the example, then compare it with the result panel.
- Explain which value each expression reads and which action changes it.
- Try the boundary cases listed in the practice task and record what you observe.
- Rebuild one matching assignment without copying, then compare behavior with the original example.
Reference
Official documentation for this topic · Vite setup requirements
