Redux Toolkit (RTK) is the official, recommended way to write Redux logic. It keeps Redux’s core ideas while removing unnecessary boilerplate and enforcing best practices.

Flow: UI → Action → Reducer → Store → UI
const counterSlice = createSlice({name: "counter",initialState: { value: 0 },reducers: {increment(state) {state.value++;},},});
RTK auto-creates:
"counter/increment"increment()const store = configureStore({reducer: { counter: counterSlice.reducer },});
RTK:
dispatch(counterSlice.actions.increment());
state.value++; // looks mutable, stays immutable
Components subscribed with useSelector get updated automatically.
Dispatch thunk → pending → (API call) → fulfilled OR rejected → state update → UI re-render
// dispatch(fetchData());const slice = createSlice({name: "data",initialState: { data: null, loading: false, error: null },reducers: {},extraReducers: (builder) => {builder.addCase(fetchData.pending, (state) => {state.loading = true;state.error = null;}).addCase(fetchData.fulfilled, (state, action) => {state.loading = false;state.data = action.payload;}).addCase(fetchData.rejected, (state, action) => {state.loading = false;state.error = action.error.message || "Failed to fetch";});},});
RTK auto-dispatches:
data/fetch/pendingdata/fetch/fulfilleddata/fetch/rejectedHandled in slice extraReducers.
Redux-Saga is a Redux middleware for handling complex async side effects like API calls, delays, retries, concurrency, and cancellation.
It uses generator functions (function*) to:
yieldcall(fn, ...args)put(action)takeLatestraceallfork(fn, ...args)