Redux Toolkit
Predictable global state with slices, store, and React hooks
createSlice
useSelector
useDispatch
createAsyncThunk
Table of Contents
- 1. Redux Basics – Core Concepts
- 2. Redux Toolkit Setup
- 3. Creating a Slice
- 4. Creating the Store
- 5. Providing Store to React
- 6. useSelector – Reading State
- 7. useDispatch – Dispatching Actions
- 8. Complete Working Example
- 9. Advanced Patterns
- 10. Key Points Summary
- 10 Basic MCQs
- 10 Advanced MCQs
- 15 Interview Questions & Answers
1. Redux Basics – Core Concepts
Redux is a predictable state container. Three core principles:
- Single source of truth – One store holds all state
- State is read-only – Actions trigger changes
- Changes via pure functions – Reducers specify how state changes
Traditional Redux Flow: Action → Dispatch → Reducer → Store → UI Update
2. Redux Toolkit Setup
Bash# Install RTK and React-Redux
npm install @reduxjs/toolkit react-redux
Project structure:
Structuresrc/
├── app/
│ └── store.js
├── features/
│ └── counter/
│ └── counterSlice.js
└── App.js
3. Creating a Slice
A slice contains reducers and actions for a feature.
JavaScript// features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit';
const initialState = {
value: 0,
status: 'idle'
};
const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increment: (state) => {
state.value += 1; // RTK uses Immer — "mutating" syntax is allowed
},
decrement: (state) => {
state.value -= 1;
},
incrementByAmount: (state, action) => {
state.value += action.payload;
}
}
});
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;
4. Creating the Store
The store holds the entire application state.
JavaScript// app/store.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from '../features/counter/counterSlice';
import userReducer from '../features/user/userSlice';
export const store = configureStore({
reducer: {
counter: counterReducer, // state.counter
user: userReducer // state.user
}
});
export const selectCounter = (state) => state.counter;
5. Providing Store to React
JavaScript// index.js or main.jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import { store } from './app/store';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')).render(
<Provider store={store}>
<App />
</Provider>
);
6. useSelector – Reading State
useSelector reads data from the Redux store.
JavaScript// CounterDisplay.js
import { useSelector } from 'react-redux';
function CounterDisplay() {
const count = useSelector((state) => state.counter.value);
const user = useSelector((state) => state.user.name);
const doubledCount = useSelector((state) => state.counter.value * 2);
return (
<div>
<p>Count: {count}</p>
<p>Doubled: {doubledCount}</p>
<p>User: {user}</p>
</div>
);
}
Best practice: Keep selectors close to the slice.
JavaScript// In slice file
export const selectCount = (state) => state.counter.value;
export const selectStatus = (state) => state.counter.status;
// Component
const count = useSelector(selectCount);
7. useDispatch – Dispatching Actions
useDispatch sends actions to update the store.
JavaScript// CounterControls.js
import { useDispatch } from 'react-redux';
import { increment, decrement, incrementByAmount } from './counterSlice';
function CounterControls() {
const dispatch = useDispatch();
return (
<div>
<button onClick={() => dispatch(increment())}>Increment</button>
<button onClick={() => dispatch(decrement())}>Decrement</button>
<button onClick={() => dispatch(incrementByAmount(5))}>Add 5</button>
</div>
);
}
8. Complete Working Example
JavaScript// App.js — Counter Example
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement, incrementByAmount } from './features/counter/counterSlice';
function App() {
const count = useSelector((state) => state.counter.value);
const dispatch = useDispatch();
return (
<div style={{ padding: '20px' }}>
<h1>Redux Toolkit Counter</h1>
<h2>Count: {count}</h2>
<button onClick={() => dispatch(increment())}>+1</button>
<button onClick={() => dispatch(decrement())}>-1</button>
<button onClick={() => dispatch(incrementByAmount(10))}>+10</button>
</div>
);
}
Async example with createAsyncThunk:
JavaScriptimport { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
export const fetchUser = createAsyncThunk(
'user/fetchUser',
async (userId) => {
const response = await fetch(`https://api.example.com/users/${userId}`);
return response.json();
}
);
const userSlice = createSlice({
name: 'user',
initialState: { data: null, loading: false, error: null },
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchUser.pending, (state) => {
state.loading = true;
})
.addCase(fetchUser.fulfilled, (state, action) => {
state.loading = false;
state.data = action.payload;
})
.addCase(fetchUser.rejected, (state, action) => {
state.loading = false;
state.error = action.error.message;
});
}
});
9. Advanced Patterns
Multiple Slices
JavaScriptexport const store = configureStore({
reducer: {
auth: authReducer,
posts: postsReducer,
notifications: notificationsReducer
}
});
const { user, isAuthenticated } = useSelector((state) => ({
user: state.auth.user,
isAuthenticated: state.auth.isAuthenticated
}));
Dispatching from useEffect
JavaScriptfunction UserProfile({ userId }) {
const dispatch = useDispatch();
const user = useSelector((state) => state.user.data);
useEffect(() => {
dispatch(fetchUser(userId));
}, [dispatch, userId]);
return <div>{user?.name}</div>;
}
10. Key Points Summary
| Hook / API | Purpose | Example |
|---|---|---|
useSelector | Read state | useSelector(state => state.counter.value) |
useDispatch | Update state | dispatch(increment()) |
createSlice | Define reducers + actions | Auto-generates action creators |
configureStore | Create store | DevTools and middleware pre-configured |
Benefits of Redux Toolkit over traditional Redux:
- Less boilerplate (no action constants, switch statements)
- Immer for mutable-like syntax
- DevTools and thunk middleware pre-configured
- Built-in best practices
Redux Toolkit MCQ Practice
10 Basic MCQs 10 Advanced MCQs10 Basic Redux Toolkit MCQs
1
Redux stores:
Explanation: Single source of truth for shared state.
2
Redux Toolkit (RTK) is:
Explanation: RTK simplifies slices, store, and async.
3
configureStore from RTK:
Explanation: Includes thunk and DevTools setup.
4
createSlice generates:
Explanation: name, initialState, reducers in one place.
5
Dispatch in React Redux uses:
Explanation: dispatch(action) to update store.
6
Selecting state uses:
Explanation: const count = useSelector(state => state.counter.value).
7
Actions in Redux are:
Explanation: RTK may use Immer inside reducers.
8
Provider from react-redux:
Explanation:
<Provider store={store}>.9
Immer in createSlice allows:
Explanation: state.value++ works inside reducers.
10
Reducers must be:
Explanation: Same input state+action => same next state.
10 Advanced Redux Toolkit MCQs
1
createAsyncThunk handles:
Explanation: API calls with standardized action types.
2
RTK Query provides:
Explanation: api slice with endpoints reduces boilerplate.
3
Normalized state with createEntityAdapter:
Explanation: ids + entities pattern for lists.
4
Middleware in store can:
Explanation: redux-thunk included by default in RTK.
5
useSelector equality fn prevents:
Explanation: shallowEqual or custom compare.
6
Combining slices uses:
Explanation: Each slice reducer mounted on key.
7
Redux DevTools show:
Explanation: Time-travel debugging in development.
8
When prefer Redux over Context?
Explanation: Context fine for simple; Redux for complex global state.
9
Serializable check middleware warns on:
Explanation: Avoid putting functions/classes in store.
10
extraReducers in slice listens to:
Explanation: Handle async thunk states in slice.
15 Redux Toolkit Interview Questions & Answers
Easy Medium Hard1What is Redux?easy
Answer: Predictable state container for JavaScript apps—global store with reducers.
2Why Redux Toolkit?medium
Answer: Reduces boilerplate, includes Immer, thunk, DevTools, and best practices.
3What is a slice?medium
Answer: RTK module combining reducer logic and action creators for one feature.
4How connect React to Redux?easy
Answer: Provider at root + useSelector/useDispatch in components.
5What is dispatch?easy
Answer: Function to send actions to the store to trigger state updates.
6Immutability in Redux?medium
Answer: State updates return new references; Immer lets write mutable syntax safely.
7createAsyncThunk use case?hard
Answer: Standardize API call loading/success/error in reducers.
8Redux vs Context?medium
Answer: Redux better for complex global state, middleware, DevTools; Context for simpler sharing.
9What is RTK Query?hard
Answer: Data fetching layer with caching built on Redux Toolkit.
10Pure reducer rule?medium
Answer: No side effects inside reducer—handle async in thunks/middleware.
11How to combine multiple reducers?medium
Answer: Pass object of slice reducers to configureStore.
12useSelector pitfalls?hard
Answer: Returning new object each time causes re-renders—memoize select result.
13Serializable state guideline?hard
Answer: Store plain JSON-like data; keep non-serializable stuff out.
14When NOT to use Redux?medium
Answer: Small apps where local state or Context is enough.
15Redux DevTools benefit?easy
Answer: Inspect every action and state change for debugging.