let renders = 0;
const log = [];
function SimulatedComponent(firstName, lastName) {
renders++;
let fullName = '';
// Bug: computing derived state in a side effect
// This causes: render with fullName='' → effect runs → setState → render again
setTimeout(() => {
fullName = firstName + ' ' + lastName;
log.push('fullName computed: ' + fullName);
renders++; // second render triggered by setState
}, 0);
log.push('render ' + renders + ': ' + (fullName || '[empty]'));
}
SimulatedComponent('Alice', 'Smith');
setTimeout(() => {
console.log(log[0]); // first render
console.log(log[1]); // effect fires
console.log(renders); // how many renders?
}, 10);let renders = 0;
const log = [];
function SimulatedComponent(firstName, lastName) {
renders++;
// Fix: compute derived value directly during render — no extra render needed
const fullName = firstName + ' ' + lastName;
log.push('render ' + renders + ': ' + fullName);
}
SimulatedComponent('Alice', 'Smith');
setTimeout(() => {
console.log(log[0]);
console.log(renders);
}, 10);Bug: fullName is derived from firstName and lastName but computed in an effect. This requires two renders: one with empty fullName, one after setState.
Explanation: fullName is computed inline during render. No useEffect, no extra render, no lag. One render with the correct value immediately.
Key Insight: If a value can be derived from state/props, compute it during render. Putting derived state in useEffect causes an extra render cycle and briefly shows stale values.