Detail page available
Component & State Observatory

React Component and State Observatory

We treat React as a UI library and design explicit ownership for local state, shared UI state, server data, URL state, and accessible interaction—without assuming one global store.

Component ownership and data-flow map

An observatory of where UI state, server data, and accessible output belong. Distinct from a deployment pipeline.

  1. Layer 1

    Component composition

    Presentational primitives and feature components arranged into screens.

  2. Layer 2

    Local UI state

    Ephemeral interaction state owned by the nearest interactive component.

  3. Layer 3

    Shared UI state

    Lifted or contextual state only when multiple siblings truly collaborate.

  4. Layer 4

    Server data

    Remote records fetched and normalized outside pure UI rendering.

  5. Layer 5

    Derived values

    Computed from existing state/props—usually not stored again.

  6. Layer 6

    Effects / integrations

    Synchronization with APIs, analytics, or browser APIs after render intent is clear.

  7. Layer 7

    Accessible output

    Roles, names, focus, and status text that make the interaction operable.

FocusUI composition
State modelOwnership-first
AccessibilityKeyboard & names
IntegrationFramework-aware

What we build with React

Illustrative interface systems—not a guaranteed delivery catalog.

  • Interactive product workspaces

    Composable panels, filters, and configuration UIs with clear local vs shared state boundaries.

  • Accessible form and onboarding flows

    Multi-step workflows with controlled inputs, error/empty states, and keyboard-complete paths.

  • Analytics and search interfaces

    URL-synchronized filters, derived result sets, and server-state hydration without duplicating truth in React state.

React State Ownership Lab

Pick a product situation to see a typed ownership model. Context is not a default; third-party stores are not automatic.

Pick a product situation to see a typed ownership model. Context is not a default; third-party stores are not automatic.

Showing state ownership model for Form workflow.

Situation

Form workflow

Multi-field input with validation, submit pending, and inline errors.

  • local

    Field values & touched flags

    Keep field state near the form unless other distant regions must edit the same draft.

    May affect

    Form root · Field controls · Inline error text

  • derived

    Validation messages

    Derive validity from values and schema; avoid mirroring errors in a second writeable store.

    May affect

    Field controls · Submit button disabled state

  • server

    Submit result

    Persist through an API/Server Action; reflect pending/error/success as explicit UI states.

    May affect

    Submit control · Status region

  • url

    Deep-linked step (optional)

    If the wizard must be shareable/restorable, encode step in the URL instead of only memory.

    May affect

    Wizard shell · Step navigation

Do not push every keystroke into global context. Do not store derived validation strings as authoritative state.

Component composition practices

Practical composition patterns for maintainable React trees—not a claim that one pattern fits every product.

Composition over oversized components

Split screens into primitives, feature components, and route containers so state and accessibility responsibilities stay discoverable.

Controlled and uncontrolled inputs

Choose controlled inputs when the parent must orchestrate validation; uncontrolled can be fine for simple isolated fields.

Reusable primitives vs feature components

Primitives stay product-agnostic. Feature components may know domain props but should not become global dumping grounds.

Compound components (when appropriate)

Use compound patterns for cohesive widgets (tabs, steppers) that share private context without exposing it app-wide.

Custom hooks

Extract reusable behavior—not junk drawers. Hooks should not hide server fetching behind opaque side effects without explicit states.

UI state vs server data

Keep remote records distinct from ephemeral UI flags to prevent sync bugs and duplicated sources of truth.

Error, loading, and empty states

Every data-backed region needs explicit non-happy paths with actionable copy—not spinners alone.

Accessibility responsibility

Custom widgets inherit the duty for names, focus order, keyboard operation, and status announcements.

Derived values instead of mirrored state

Illustrative pattern—derive totals from selections rather than storing a second writeable total.

type OptionId = "basic" | "pro" | "scale";

type Selection = {
  optionId: OptionId;
  seats: number;
};

const PRICE: Record<OptionId, number> = {
  basic: 20,
  pro: 45,
  scale: 90,
};

export function priceFor(selection: Selection): number {
  return PRICE[selection.optionId] * selection.seats;
}

Narrow provider instead of app-wide context

Illustrative pattern—limit shared UI state to the feature subtree that needs it.

type WizardValue = {
  step: number;
  answers: Record<string, string>;
  setStep: (step: number) => void;
};

const WizardContext = createContext<WizardValue | null>(null);

export function useWizard(): WizardValue {
  const value = useContext(WizardContext);
  if (!value) {
    throw new Error("useWizard requires WizardProvider");
  }
  return value;
}

Render propagation explainer

How updates can move through a tree. Re-renders are normal; optimize from evidence.

  1. 01

    State owner

    The component that calls the setter owns the write path.

  2. 02

    Child consumers

    Children re-render when received props/context values change.

  3. 03

    Derived output

    Pure calculations update when inputs change—no extra store required.

  4. 04

    Memoization boundary (optional)

    Memo/PureComponent boundaries are tools for measured hot paths—not defaults.

  5. 05

    Server-state subscription

    Query/subscription libraries notify UI when remote data identity changes.

A re-render is not automatically a bug. Optimize from evidence—profiling and user-perceived latency—not from fear of renders.

React delivery workflow

A React-specific engineering sequence centered on ownership, accessibility, and release hardening.

  1. 1

    Interaction and state inventory

    List user intents, ephemeral UI flags, shareable parameters, and remote records before choosing libraries.

  2. 2

    Component boundary design

    Draw primitive vs feature vs route containers so ownership and testing seams are obvious.

  3. 3

    Data ownership and integration

    Define how server data enters the tree, how mutations complete, and how failures surface.

  4. 4

    Accessibility and keyboard behavior

    Specify tab order, focus returns, names for icon controls, and non-color status cues up front.

  5. 5

    Error, loading, and empty architecture

    Design non-happy paths as first-class UI, including retry and partial-data presentations.

  6. 6

    Testing strategy

    Prefer user-centric component tests for interactions; add integration coverage for critical state machines.

  7. 7

    Performance profiling and release hardening

    Measure before memoizing; budget client islands; verify no meaningful content is client-only.

Common React architecture failure modes

Practical problems to design against when composing interfaces and state.

Oversized all-purpose components

God components mix fetching, layout, and business rules until changes become unsafe.

Duplicated state

The same fact stored in props, context, and local state drifts out of sync.

Unnecessary effects

Effects used to compute derivable values create timing bugs and extra renders.

Stale closure behavior

Handlers capture old state when dependencies are incomplete or setters are misused.

Unstable list keys

Index keys on reorderable lists scramble state and accessibility relationships.

Derived data stored as state

Totals and labels mirrored into writeable state become inconsistent with sources.

Global context overuse

App-wide providers for frequent updates amplify render fan-out.

Inaccessible custom controls

Divs with onClick skip keyboard users and assistive technologies.

Premature memoization

useMemo/useCallback everywhere obscures intent without proven benefit.

Client-only meaningful content

Putting critical explanations only inside client trees harms SEO and no-JS users.

Missing error/loading/empty states

Silent blank panels appear when networks fail or datasets are empty.

Choose or reconsider React

State ownership recommendations are educational decision models. They are not universal performance guarantees or library mandates.

Choose when

  • The product needs rich, composable client interfaces with reusable UI primitives.
  • Teams benefit from explicit component boundaries and typed props.

Reconsider when

  • The surface is mostly static content with negligible interaction and no component reuse need.

Inventory interaction and state before coding. Prefer composition and derived values. Profile before memoizing. Verify keyboard and screen-reader paths for custom controls.

Common React questions

Is React a full application framework?

No. React is a UI library. Routing, data fetching, SEO metadata, and deployment usually come from a framework or surrounding architecture such as Next.js.

Should every state problem use Context or a global store?

No. Prefer local state, lifted state, URL state, or server state first. Context and shared stores help when many distant components genuinely share UI concerns—not as a default.

Does memoization always improve React performance?

No. Memoization can help when profiling shows expensive re-renders, but premature memoization adds complexity without guaranteed benefit.

Implementation insight

Design React systems as an observatory of ownership: know what is local, lifted, derived, or remote—and keep meaningful content outside the client-only zone.

Next step

Discuss your React interface architecture

I would like to discuss React component composition, state ownership, and accessible interface design for our product.

Begin stack consultation