Redux Basics for React Interviews
What is Redux?
Section titled “What is Redux?”Redux is a predictable state management library used to manage global application state. It stores the entire application state in a single store and updates state through dispatched actions.
Benefits
Section titled “Benefits”- Centralized state management
- Predictable state updates
- Easier debugging
- Time-travel debugging
- Better state sharing between components
What Problem Does Redux Solve?
Section titled “What Problem Does Redux Solve?”Redux solves:
- Prop drilling
- Managing complex shared state
- Synchronizing state across multiple components
- Maintaining predictable state changes
Example:
Instead of passing user information through multiple component levels, Redux stores it globally.
Core Principles of Redux
Section titled “Core Principles of Redux”1. Single Source of Truth
Section titled “1. Single Source of Truth”The entire application state is stored in one Store.
2. State is Read-only
Section titled “2. State is Read-only”State cannot be modified directly. Changes happen through Actions.
3. Changes are Made with Pure Functions
Section titled “3. Changes are Made with Pure Functions”Reducers update the state.
(state, action) => newStateMain Components of Redux
Section titled “Main Components of Redux”Stores application state.
const store = configureStore({ reducer: rootReducer});Action
Section titled “Action”Describes what happened.
{ type: "ADD_TODO", payload: todo}Reducer
Section titled “Reducer”Updates state based on action.
function todoReducer(state = [], action) { switch (action.type) { case "ADD_TODO": return [...state, action.payload]; default: return state; }}Dispatch
Section titled “Dispatch”Sends an action to the reducer.
dispatch(addTodo(todo));Redux Data Flow
Section titled “Redux Data Flow”flowchart TD
A[Component] --> B[Dispatch Action]
B --> C[Reducer]
C --> D[Store Updated]
D --> E[UI Re-renders]
- User performs an action.
- Component dispatches an action.
- Action reaches the reducer.
- Reducer creates a new state.
- Store updates its state.
- UI re-renders.
The Store holds the entire Redux state tree.
const store = configureStore({ reducer: rootReducer});Only one store is generally recommended.
Action Creators
Section titled “Action Creators”Functions that return actions.
const increment = () => ({ type: "INCREMENT"});Usage:
dispatch(increment());Reducers
Section titled “Reducers”Reducers are pure functions that take the current state and an action and return a new state.
function counterReducer(state = 0, action) { switch (action.type) { case "INCREMENT": return state + 1; default: return state; }}Why Must Reducers Be Pure?
Section titled “Why Must Reducers Be Pure?”Reducers:
- Don’t modify existing state
- Don’t call APIs
- Don’t have side effects
- Return the same output for the same input
Bad:
state.count++;Good:
return { ...state, count: state.count + 1};Immutable State
Section titled “Immutable State”State should never be modified directly.
Wrong:
state.user.name = "John";Correct:
return { ...state, user: { ...state.user, name: "John" }};Redux Toolkit (RTK)
Section titled “Redux Toolkit (RTK)”Redux Toolkit is the official recommended way to write Redux.
Benefits
Section titled “Benefits”- Less boilerplate
- Built-in Immer support
- Built-in thunk middleware
- Easier configuration
const counterSlice = createSlice({ name: "counter", initialState: { value: 0 }, reducers: { increment: (state) => { state.value++; } }});Why Redux Toolkit Is Preferred
Section titled “Why Redux Toolkit Is Preferred”| Traditional Redux | Redux Toolkit |
|---|---|
| More boilerplate | Less code |
| Manual store setup | configureStore |
| Manual action types | createSlice |
| Manual immutable updates | Immer support |
| Complex | Simple |
createSlice()
Section titled “createSlice()”Generates:
- Reducer
- Actions
- Action types
const userSlice = createSlice({ name: "user", initialState: {}, reducers: { setUser(state, action) { return action.payload; } }});configureStore()
Section titled “configureStore()”const store = configureStore({ reducer: { user: userReducer, product: productReducer }});React Redux Hooks
Section titled “React Redux Hooks”useSelector()
Section titled “useSelector()”Reads data from the Redux store.
const count = useSelector( state => state.counter.value);useDispatch()
Section titled “useDispatch()”Dispatches actions.
const dispatch = useDispatch();
dispatch(increment());useState vs Redux
Section titled “useState vs Redux”| useState | Redux |
|---|---|
| Local state | Global state |
| Component-specific | Shared across app |
| Simple | Complex state management |
| No middleware | Middleware support |
Middleware
Section titled “Middleware”Middleware sits between dispatch and the reducer.
flowchart LR
A[Dispatch] --> B[Middleware]
B --> C[Reducer]
Used for:
- API calls
- Logging
- Authentication
- Error handling
Examples:
- Redux Thunk
- Redux Saga
Redux Thunk
Section titled “Redux Thunk”export const fetchUsers = () => { return async (dispatch) => { const res = await fetch("/users"); dispatch(setUsers(await res.json())); };};Reducers should not perform API calls because they must remain pure, synchronous, and side-effect free.
Senior-Level Interview Topics
Section titled “Senior-Level Interview Topics”When Would You Avoid Redux?
Section titled “When Would You Avoid Redux?”Avoid Redux when:
- The application is small.
- There is very little shared state.
- React Context is sufficient.
Use Context API for themes, language, or simple authentication state. Use Redux for complex business state. See the React Context API Interview Guide for the full Context API vs Redux comparison.
How Redux Improves Performance
Section titled “How Redux Improves Performance”- Normalized state
- Memoized selectors
- Selective re-renders via
useSelector - Immutable updates
RTK Query
Section titled “RTK Query”const api = createApi({ baseQuery: fetchBaseQuery({ baseUrl: "/api" }), endpoints: (builder) => ({ getUsers: builder.query({ query: () => "/users" }) })});Benefits:
- Caching
- Refetching
- Loading states
- Error handling
Redux vs Zustand
Section titled “Redux vs Zustand”| Redux | Zustand |
|---|---|
| Enterprise scale | Lightweight |
| More boilerplate | Minimal code |
| Rich middleware ecosystem | Simpler |
| Best for large apps | Best for small/medium apps |
Redux Toolkit is typically preferred for enterprise applications with complex state management and debugging requirements.
Frequently Asked Interview Questions
Section titled “Frequently Asked Interview Questions”Can Redux work without React?
Yes. Redux is framework-independent.
Can we have multiple stores?
Yes, but a single store is the recommended architecture.
What is the single source of truth?
The Redux Store.
Which hook reads state from Redux?
useSelector().
Which hook dispatches actions?
useDispatch().
Which Redux approach is recommended today?
Redux Toolkit (RTK).
Summary
Section titled “Summary”- Redux centralizes application state into a predictable single store.
- State updates occur by dispatching actions that are handled by pure reducers.
- Redux Toolkit is the recommended modern approach because it significantly reduces boilerplate.
- Middleware such as Redux Thunk enables asynchronous logic while keeping reducers pure.
- Use Redux for complex shared state, while React Context is often sufficient for simpler global state.