Consider this React functional component using useState:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
console.log('Rendering with count:', count);
return (
<button onClick={() => setCount(count)}>Count: {count}</button>
);
}What happens when the button is clicked?
import React, { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); console.log('Rendering with count:', count); return ( <button onClick={() => setCount(count)}>Count: {count}</button> ); }
Think about whether React re-renders when the state setter is called with the same value.
React skips re-rendering if the state value passed to setCount is the same as the current state. Here, setCount(count) sets the state to the existing value, so no re-render occurs.
Look at this React component:
import React, { useState } from 'react';
function Clicker() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
setCount(count + 1);
}
return (
<button onClick={handleClick}>Clicked {count} times</button>
);
}What will the button display after clicking it once?
import React, { useState } from 'react'; function Clicker() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); setCount(count + 1); } return ( <button onClick={handleClick}>Clicked {count} times</button> ); }
Remember that state updates may be batched and the count variable does not update immediately.
Both setCount(count + 1) calls use the same count value (0). React batches them, so the state updates to 1, not 2.
Examine this React component:
import React, { useState, useEffect } from 'react';
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
setSeconds(seconds + 1);
});
return <div>Seconds: {seconds}</div>;
}What causes the infinite re-rendering?
import React, { useState, useEffect } from 'react'; function Timer() { const [seconds, setSeconds] = useState(0); useEffect(() => { setSeconds(seconds + 1); }); return <div>Seconds: {seconds}</div>; }
Think about when useEffect runs and what happens when state updates inside it.
Without a dependency array, useEffect runs after every render. Inside it, setSeconds(seconds + 1) updates state, triggering another render, causing an infinite loop.
Given this component wrapped with React.memo:
const Display = React.memo(function Display({ value }) {
console.log('Rendering Display');
return <div>Value: {value}</div>;
});Which parent component usage prevents Display from re-rendering when value does not change?
const Display = React.memo(function Display({ value }) { console.log('Rendering Display'); return <div>Value: {value}</div>; });
Consider how React.memo compares props and when new objects cause re-renders.
Option C passes a primitive constant val which does not change, so Display skips re-render. Option C passes a new random number each render. Option C passes a new object each render causing re-render. Option C uses useMemo but for a primitive, which is unnecessary but still works; however, option C is simpler and correct.
In React, when passing functions as props, why is useCallback useful to prevent unnecessary re-renders of child components?
Think about how React compares props to decide if a child should re-render.
React compares props by reference. Without useCallback, a new function is created on every render, causing child components to re-render. useCallback returns the same function reference unless dependencies change, helping React skip unnecessary re-renders.