Two-Way Data Flow in React: Hooks + Redux

While learning React hooks, I focused a lot on what each hook does (useEffect, useCallback, etc.). But after working on a real client-facing React application with Redux, I realized that hooks are not just APIs — they form a data-flow architecture.

1. Redux State Must Be the Single Source of Truth

In a real app, multiple components and widgets may read and write shared data. Only one place should be authoritative.

In our case:

  • Redux holds the ground truth (selectedSecurities)
  • UI components and widgets (search bar, table, pills, etc.) must derive their state from Redux — not own it

Rule:

  • UI state should be reconciled from Redux, not partially owned by event handlers.

2. useEffect Is a Reconciler, Not Just “Side Effects”

Effect = “Make UI match the model”.

useEffect(() => {
  // reconcile UI with Redux state
}, [reduxState]);

3. UI Events Should Only Express Intent — Not Mutate UI State

Handlers should:

  • Dispatch Redux actions
  • Express what happened

They should not directly mutate UI bookkeeping state.

// Good
dispatch(removeSecurity({id: security.id}));

// Not ideal
displayedIdsRef.current.delete(security.id); // double ownership

Let Redux update → let useEffect reconcile UI.
This avoids double ownership, race conditions, and stale UI bugs.

4. Dependency Arrays Are About Closure Correctness — Not Performance

useCallback and useEffect dependencies are not “performance hints”. They define what version of state your function is allowed to see. If a handler reads selectedSecurities, it must include it in deps — otherwise it becomes logically incorrect.

5. Stable Dependencies Still Belong in the Dependency Array

Redux’s dispatch is stable — but still belongs in deps:

useCallback(() => {
  dispatch(...)
}, [dispatch]);

This keeps hooks semantically correct, future-proof, and concurrency-safe.

6. Real Apps Are Bidirectional Data Flows

Real systems have two directions:

Direction Hook
Redux -> UI useEffect (reconciliation)
UI -> Redux useCallback (intent dispatch)

UI events dispatch → Redux updates → effect reconciles UI/ref.

React Hooks are not just tools — they are data-flow constraints. They enforce how data moves, who owns truth, and how UI stays consistent.