Skip to content

React useState Interview Guide

useState is a React Hook that allows functional components to maintain state.

const [count, setCount] = useState(0);
  • count -> Current state value
  • setCount -> Function to update state
  • 0 -> Initial value

Without state:

let count = 0;
function increment() {
count++;
}

The UI will not update.

With useState:

const [count, setCount] = useState(0);
function increment() {
setCount(count + 1);
}

React automatically re-renders the component.

Interview Answer

useState allows React components to store data that changes over time and automatically re-render the UI when that data changes.


setCount(count + 1);

React:

  1. Updates state
  2. Schedules a re-render
  3. Creates a new Virtual DOM
  4. Compares it with the previous Virtual DOM
  5. Updates only the changed DOM nodes
flowchart TD
    A[setState Called] --> B[State Updated]
    B --> C[Schedule Render]
    C --> D[Create Virtual DOM]
    D --> E[Diff Previous vs New]
    E --> F[Update Real DOM]

State updates are scheduled asynchronously.

setCount(count + 1);
console.log(count);

Output:

Old value

Because React hasn’t completed the re-render yet.

Incorrect:

setCount(count + 1);

Correct:

setCount(prev => prev + 1);

Use functional updates whenever the next state depends on the previous one.

setCount(count + 1);
setCount(count + 1);

Both updates use the same stale value.

Correct:

setCount(prev => prev + 1);
setCount(prev => prev + 1);

Final result: +2

const [user, setUser] = useState({
name: "Abi",
age: 30
});

Incorrect:

setUser({
age: 31
});

Correct:

setUser({
...user,
age: 31
});
const [items, setItems] = useState([]);

Add an item:

setItems([...items, "Apple"]);

Incorrect:

items.push("Apple");
setItems(items);

Correct:

setItems([...items, "Apple"]);

React detects changes using object references.

Yes.

setCount(5);

If the state value is unchanged.

setCount(5);
setCount(5);
  • State changes
  • Props changes
  • Parent component re-renders

Incorrect:

const [data] = useState(expensiveCalculation());

Correct:

const [data] = useState(() => expensiveCalculation());

Runs only once during the initial render.

setCount(c => c + 1);
setFlag(true);

React batches updates into a single render for better performance.

setTimeout(() => {
console.log(count);
}, 5000);

Solutions:

setCount(prev => prev + 1);

or useRef().

No.

Incorrect:

if (isLoggedIn) {
useState("");
}

Correct:

const [name, setName] = useState("");

No.

for (let i = 0; i < 5; i++) {
useState();
}

Hooks must always be called in the same order.

useState useRef
Causes re-render No re-render
Stores UI state Stores mutable reference
UI updates automatically UI does not update
const ref = useRef(0);
ref.current++;

See the React useRef Interview Guide for persistence mechanics, forwardRef/useImperativeHandle, and avoiding stale closures.

useState useReducer
Simple state Complex state
Minimal logic Complex business logic
Easy API Reducer pattern
const [count, setCount] = useState(0);
const [state, dispatch] = useReducer(reducer, initialState);

React stores hook state internally in the Fiber tree.

flowchart TD
    A[Component Render] --> B[React Fiber]
    B --> C[Retrieve Hook State]
    C --> D[Render UI]

React compares object references.

oldObj === newObj

If the reference changes, React knows the state changed.

  1. Using stale state.
  2. Mutating arrays.
  3. Mutating objects.
  4. Calling Hooks conditionally.

Frequently Asked Senior Interview Questions

Section titled “Frequently Asked Senior Interview Questions”

To support batching and improve rendering performance.

  • Complex state transitions
  • Multiple related state values
  • Centralized business logic
setCount(prev => prev + 1);

They avoid stale state problems.

  • Shared application state -> Context API / Redux
  • Complex state -> useReducer
  • Mutable non-UI values -> useRef
  • Server state -> TanStack Query / React Query
  • useState manages local component state in functional components.
  • State updates are asynchronous, immutable, and batched.
  • Use functional updates when the next state depends on the previous state.
  • Never mutate objects or arrays directly.
  • Follow the Rules of Hooks by calling Hooks only at the top level.
  • Prefer useReducer for complex state and useRef for mutable values that should not trigger re-renders.