Redux & Redux Toolkit — App-Wide State ManagementEntry 5 of 11
Dispatching Actions and Payloads
useDispatch returns the store's dispatch function. Calling it with an action triggers the reducer.
Notes
- Call
useDispatch()once at the top of the component. - An action with only a
typeis enough for fixed changes (increment, toggle). - Extra properties on the action carry a payload (
{ type: 'increase', amount: 10 }), so one action handles variable values. - Adding new state (like
showCounter) means: add it to the initial state, handle it in the reducer, and keep returning it from every other case.
What / Why / When
- What
Triggering state changes from components.
- Why
Components describe what happened; the reducer decides how state changes.
- When
Any user interaction or event that changes shared state.
Code compare
import { useDispatch, useSelector } from "react-redux";import type { CounterState } from "../store";export default function Counter() { const dispatch = useDispatch(); const counter = useSelector((state: CounterState) => state.counter); const show = useSelector((state: CounterState) => state.showCounter); return ( <main> {show && <div>{counter}</div>} <button onClick={() => dispatch({ type: "increment" })}>Increment</button> <button onClick={() => dispatch({ type: "increase", amount: 10 })}>Increase by 10</button> <button onClick={() => dispatch({ type: "decrement" })}>Decrement</button> <button onClick={() => dispatch({ type: "toggle" })}>Toggle Counter</button> </main> );}@Component({ selector: "app-counter", template: ` <main> @if (show()) { <div>{{ counter() }}</div> } <button (click)="increment()">Increment</button> <button (click)="increase(10)">Increase by 10</button> <button (click)="decrement()">Decrement</button> <button (click)="toggle()">Toggle Counter</button> </main> `,})export class CounterComponent { private store = inject(Store); protected counter = this.store.selectSignal(counterFeature.selectCounter); protected show = this.store.selectSignal(counterFeature.selectShowCounter); increment() { this.store.dispatch(CounterActions.increment()); } increase(amount: number) { this.store.dispatch(CounterActions.increase({ amount })); } decrement() { this.store.dispatch(CounterActions.decrement()); } toggle() { this.store.dispatch(CounterActions.toggleCounter()); }}Differences and gotchas
- Hand-typed
typestrings are typo-prone:'incremnt'fails silently. RTK (Entry 6) and NgRx both generate action creators to avoid this.
Quick reference
| Task | React | Angular |
|---|---|---|
| Get dispatch | const dispatch = useDispatch() | inject(Store) |
| Simple action | dispatch({ type: 'increment' }) | store.dispatch(CounterActions.increment()) |
| With payload | dispatch({ type: 'increase', amount: 10 }) | store.dispatch(CounterActions.increase({ amount: 10 })) |