Keeping Components Pure
Keeping Components Pure
A marks report may render more than once even when the student has not clicked anything. If rendering changes shared records or increments a global counter, simply displaying a report could corrupt its information.
A pure rendering calculation produces the same interface from the same inputs and does not change pre-existing values. React can render again, restart work or check components during development, so rendering must not depend on running exactly once.
Explain
Calculate a total without altering a supplied student record.
Trace
Sort a copy while preserving the original student order.
Apply
Identify a write or notification that should not happen during render.
Pure Components: follow the relationship
Existing inputs
The caller supplies marks and their original order.
Fresh calculation
The component creates a new total or sorted copy.
Inputs stay intact
Rendering again starts from the same unchanged supplied data.
Build the mental model
Calculate new values from props without altering those props. A report can sum marks or create a new sorted copy of a list. A user action belongs in an event handler, while synchronization with an external system belongs in an Effect when required.
Repeatability is a practical debugging tool
To review a rendering calculation, ask whether calling it twice with the same inputs changes anything outside the call. If the second call starts from a modified record, a global counter or a mutated array, the result depends on execution history rather than the supplied inputs.
Pure rendering also makes abandoned work safe: React can calculate an interface that it never commits without causing an unintended school action. Do not charge a fee, send an attendance notification or write a record during render. Those effects need an intentional action or synchronization boundary.
Read the complete React example
The example computes a total from two supplied marks. It does not add a total field to the student object. The practice copies an array before sorting it, preserving the parent’s original order and allowing both views to coexist.
React · JavaScript with JSX
import React from 'react';
function Total({ maths, science }) {
const total = maths + science;
return <p>Total: {total}</p>;
}
export default function App() {
return <main><h1>Asha's report</h1><Total maths={40} science={35} /></main>;
}Expected screen and behavior
Initial screen: Asha's report Total: 75Connect the source to the screen
React · main example
import React from 'react';
function Total({ maths, science }) {
const total = maths + science;
return <p>Total: {total}</p>;
}
export default function App() {
return <main><h1>Asha's report</h1><Total maths={40} science={35} /></main>;
}Mutating a fresh local object created during that render is different from mutating an object supplied by a caller. The local value has no earlier observer. Keep the boundary clear: props and previously stored state are existing inputs, while fresh derived values belong to the current calculation.
Avoid the common mistakes
Array sort changes its receiver. Sorting a props array directly therefore changes the parent’s data. Copy first, or use a non-mutating sorting API when the target environment supports it. Development Strict Mode may call rendering calculations extra times to expose impurity; it is not a promise of only two calls.
Practice before reading the solution
React · starting example
import React from 'react';
function Total({ maths, science }) {
const total = maths + science;
return <p>Total: {total}</p>;
}
export default function App() {
return <main><h1>Asha's report</h1><Total maths={40} science={35} /></main>;
}Display marks in descending order while also showing the original student order.
Predict the initial visible text and explain which values determine it. Then inspect the worked solution below. Change one relevant input in your local project and check whether the screen follows your prediction. A working screen should be checked for the intended meaning, not merely the absence of an error.
Worked practice solution
The solution sorts a spread copy and leaves the supplied records untouched. Both paragraphs can therefore be predicted from the original data. Local derivation avoids a state update or Effect just to produce a sorted display.
React · JavaScript with JSX
import React from 'react';
function Ranking({ students }) {
const ranked = [...students].sort((a, b) => b.marks - a.marks);
return <p>Ranking: {ranked.map(student => student.name).join(', ')}</p>;
}
export default function App() {
const students = [{ name: 'Ravi', marks: 60 }, { name: 'Asha', marks: 75 }];
return <main><Ranking students={students} /><p>Original: {students.map(student => student.name).join(', ')}</p></main>;
}Expected screen and behavior
Initial screen: Ranking: Asha, Ravi Original: Ravi, AshaCheck your reasoning
Choose the explanation that matches React and JavaScript behavior. Review the reasoning for each alternative before moving on.
Use the idea in the next lesson
A pure rendering calculation produces the same interface from the same inputs and does not change pre-existing values. React can render again, restart work or check components during development, so rendering must not depend on running exactly once.
Continue with Handling Events. Revisit Component Composition when the relationship between inputs and the resulting screen needs another look.
Read the primary reference: React documentation on Keeping Components Pure.
Reaching the recap and completing the quizzes are separate milestones.