Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

Technology handbook

Redux

Predictable state transitions, actions, reducers, selectors, middleware, React integration and legacy migration.

Topics
34
Sections
5

Hooks

useStore

Reach the store instance for rare imperative work without subscribing to any state.

  • useStore returns the Provider's Redux store instance.
  • Calling getState does not subscribe the component.
  • Prefer useSelector for values that must update the UI.

useSelector equality

Pass shallowEqual or a custom comparison for selections that return objects or arrays.

  • The default comparison checks selected result identity.
  • Use shallowEqual for suitable flat object selections.
  • A custom comparator must cover every rendered field.

Selector identity in hooks

A selector returning a fresh object re-renders on every action, whatever the values inside it.

  • Returning a fresh object defeats default equality checking.
  • Select primitives separately or memoize object derivations.
  • Keep selector inputs stable across unrelated dispatches.

Stable dispatch identity

dispatch never changes, which is why it is safe to list in a dependency array.

  • The dispatch reference is stable while the store instance is unchanged.
  • Include dispatch in effect and callback dependency lists.
  • Replacing the Provider's store can change that reference.

Selecting inside list rows

Select one item by id in the row component rather than the whole collection in the parent.

  • Pass a record ID to each connected row.
  • Select that record instead of subscribing to all entities.
  • Use stable list keys to preserve row identity.

Hooks versus connect

What replaced mapStateToProps, and why each hook consumer subscribes on its own.

  • Hooks read context and subscribe within function components.
  • connect wraps components with selected props and dispatch bindings.
  • Test behavior during incremental migration between bindings.

Reading state in handlers

Prefer a thunk or getState for a value needed only at click time, not a new subscription.

  • Use getState inside a thunk for the latest store snapshot.
  • Do not assume a captured render value has updated after dispatch.
  • Subscribe only when a value affects rendered output.

Hooks and the store Provider

Every hook resolves the store from context, so a missing Provider fails at the first read.

  • Mount Provider above every React Redux hook consumer.
  • Pass the correct store when testing an isolated subtree.
  • Separate Providers can intentionally expose separate state domains.

Redux core

Single state tree

Model shared application state with clear domains rather than treating every component value as global.

  • Organize shared state into meaningful domain slices.
  • Keep derived values out of the canonical state tree.
  • Leave temporary form edits local when sharing is unnecessary.

Actions and action creators

Describe events with serializable payloads and centralize their creation when useful.

  • Actions need a type identifying the event being described.
  • Put event data in a predictable serializable payload.
  • Action creators standardize payload construction for callers.

Pure reducers

Compute next state from previous state and action without I/O, randomness or mutation.

  • Return the next state without changing the previous state.
  • Move network requests and other effects into middleware or thunks.
  • Return the existing reference for irrelevant actions.

dispatch and subscribe

Understand action delivery and how consumers observe committed state changes.

  • Dispatch a plain action to run the reducer synchronously.
  • Subscribers read the committed state through getState.
  • Middleware can extend dispatch to support other input forms.

combineReducers

Compose independently owned state slices under a predictable root state shape.

  • Each slice reducer owns one key of the root state.
  • Provide a valid initial value when state is undefined.
  • Return unchanged slice state for actions it does not handle.

Immutable update patterns

Copy only changed paths and retain unchanged references to support efficient comparisons.

  • Copy every ancestor of a changed nested value.
  • Reuse untouched branches to preserve useful identity checks.
  • Array copying alone does not copy the objects inside it.

Redux data modeling

Normalized state

Store entities by ID and reference them instead of duplicating nested records.

  • Keep entities in an ID-indexed lookup with ordered IDs.
  • Reference shared entities by ID instead of duplicating records.
  • Update a record once so all views use consistent data.

Selectors

Encapsulate state shape and derive values without forcing every caller to know internal layout.

  • Hide state layout behind named selector functions.
  • Accept state and optional arguments as explicit inputs.
  • Keep selectors deterministic and free of dispatch side effects.

Memoized selectors

Cache expensive derivations when their input references are unchanged.

  • Use stable input selectors for expensive derived calculations.
  • Recompute only when the relevant inputs change.
  • Choose cache scope carefully for parameterized list selectors.

State machines

Represent valid loading and workflow states explicitly rather than using contradictory booleans.

  • Represent mutually exclusive states with an explicit status field.
  • Define allowed transitions for pending, success and failure.
  • Prevent impossible combinations of independent loading flags.

Event-style actions

Name what happened instead of exposing implementation-level field setters everywhere.

  • Describe domain events such as orderSubmitted.
  • Let multiple slices respond to the same meaningful event.
  • Avoid exposing every internal field as a public setter.

Local versus global state

Keep temporary UI state local unless sharing or lifecycle requirements justify global ownership.

  • Keep transient input and hover state close to their component.
  • Share state when distant consumers require coordinated updates.
  • Consider reset lifetime before promoting data to the store.

Middleware & async

Middleware pipeline

Wrap dispatch to observe or transform actions before reducers receive them.

  • Middleware wraps dispatch before actions reach reducers.
  • Call next to continue through the remaining middleware chain.
  • Keep middleware ordering explicit when dependencies interact.

Thunk middleware

Run async logic that can dispatch actions and read current state through an explicit function contract.

  • A thunk receives dispatch and getState as arguments.
  • Dispatch lifecycle actions around asynchronous operations.
  • Return a promise when callers need to await completion.

Async request lifecycle

Track pending, fulfilled and rejected outcomes with request identity to handle races.

  • Track request identity along with pending and error state.
  • Accept completion only for the still-relevant request.
  • Distinguish canceled requests from user-visible failures.

Store enhancers

Distinguish altering store capabilities from intercepting actions with middleware.

  • An enhancer wraps store creation and may alter store capabilities.
  • Middleware focuses on intercepting dispatched values.
  • Compose enhancers in a documented order when maintaining legacy setup.

Persistence and rehydration

Version stored state and avoid treating old cached data as permanently valid.

  • Persist only approved durable state fields.
  • Version and migrate stored snapshots before using them.
  • Revalidate remote data after restoring an old cache.

Redux DevTools

Inspect action history and state differences while understanding the limits of replaying side effects.

  • Inspect dispatched events and the state changes they produced.
  • Time travel replays state transitions, not external side effects.
  • Sanitize action and state data before sharing debugging sessions.

React Redux & migration

Provider

Expose the intended store instance to a React subtree without cross-request state leakage.

  • Provide one stable store instance to the intended React subtree.
  • Create request-scoped instances for server-rendered user state.
  • Initialize test Providers with realistic state fixtures.

useSelector

Subscribe to selected values and keep reference behavior compatible with equality checking.

  • Select only the fields the component actually renders.
  • Keep selected object identities stable when values are unchanged.
  • Handle missing records when parent and child updates overlap.

useDispatch

Dispatch typed application actions and thunks from UI event handlers.

  • Get dispatch from the same Provider as the component's selectors.
  • Send actions from handlers rather than during render.
  • Use application dispatch types when dispatching thunks.

connect and mapStateToProps

Understand the older React binding when maintaining existing applications.

  • mapStateToProps converts store state into component props.
  • mapDispatchToProps exposes event-oriented action callbacks.
  • Keep prop derivations stable to avoid needless wrapper updates.

Typed hooks

Define reusable hooks with application state and dispatch types.

  • Infer RootState and AppDispatch from the configured store.
  • Export pre-typed selector and dispatch wrappers once.
  • Import those wrappers instead of repeating casts in components.

Reducer and integration tests

Test meaningful state transitions and user flows instead of relying only on mocked dispatch calls.

  • Verify reducer transitions from meaningful starting states.
  • Render connected components with a real test store.
  • Assert visible outcomes of actions and asynchronous flows.

Legacy createStore migration

Move legacy setup toward configureStore without rewriting all reducers at once.

  • Replace store creation with configureStore first.
  • Keep existing reducers while checking middleware compatibility.
  • Resolve serialization warnings before removing safeguards.

Redux Toolkit adoption

Replace repetitive action and reducer boilerplate with slices and supported async patterns.

  • Migrate one domain to createSlice at a time.
  • Replace handwritten request boilerplate with supported Toolkit APIs.
  • Keep action behavior compatible while updating consumers.

Sources

  • Redux official documentation

Ask follow-up questions on any topic in your dashboard.

Start learning