useState vs useRef vs useReducer
🔹 1. useState
Section titled “🔹 1. useState”- Purpose : For simple, reactive state (UI should update when the value changes).
- Re-renders : ✅ Yes (when state updates).
- When To use : Counters, Form inputs, toggle, etc
- Eg:
const Counter = () => { const [count, setCount] = React.useState(0)
return <button onClick={()=> setCount(count++)}>{count}</button> }👉 Anytime you want UI to re-render when the value changes → useState.
🔹 2. useRef
Section titled “🔹 2. useRef”- Purpose : For storing mutable value that does not trigger re-render.
- Re-renders : ❌ No (updating
.currentwon’t re-render). - When To use :
- Accessing DOM element directly.
- Keeping values across renders(like setTimeout IDs, previous values).
- Eg:
function Timer (){ const timer = React.useRef(null) function startTimer (){ timer.current = setInterval(()=>{console.log(tick)}, 1000) } function clearTimer(){ clearInterval(timer.current) } return( <> <button onClick={startTimer}>Start</button> <button onClick={clearTimer}>Stop</button> </> ) }👉 Use useRef when you want to persist a value but don’t need re-renders.
🔹 3. useReducer
Section titled “🔹 3. useReducer”- Purpose : For complex state logic (state transitions based on actions).
- Re-renders : ✅ Yes (when state updates).
- When To use :
- When state has multiple sub values.
- When next state depends on previous state.
- When using Redux like pattern in single component.
- Eg:
const Counter = () => { function reducer (state, action){ switch(action.type){ case 'increment': return {count: state.count + 1} case 'decrement': return {count: state.count - 1} } } const [state, dispatch] = React.useReducer(reducer, {count: 0}) return ( <> <p>{state.count}</p> <button onClick={()=> dispatch({type: 'increment'})}>+</button> <button onClick={()=> dispatch({type: 'decrement'})}>-</button> </> ) }👉 Use useReducer for state machines or complex logic.
🧠 Quick Comparison
Section titled “🧠 Quick Comparison”| Hook | Re-renders UI? | Best For |
|---|---|---|
| useState | ✅ Yes | Simple state updates (counter, form field) |
| useRef | ❌ No | Persist values without re-render (DOM refs, timers, prev values) |
| useReducer | ✅ Yes | Complex state logic, multiple actions, Redux-like flow |
Quick Interview Answer ->
Section titled “Quick Interview Answer ->”“I use useState for simple UI states, useRef when I need to persist values without re-rendering the UI(like timers or DOM refs) and useReducer for complex
logic where multiple actions update state in predictable ways.”