15.7 · Effects and cancellation, modelling state, composing reducers

The first pass explained why one-way state is predictable. In practice the hard parts are everything around the pure function: effects that finish out of order, states that should not exist, features that must compose, and time.

Mental model. A reducer is only as trustworthy as the effects it launches and the states it allows. Make illegal states unrepresentable, make stale results harmless, and make time a dependency.

Effects and state shape

Out-of-order responses, cancellation, and enums instead of flags.

  1. In a reducer-style store, how do you stop a slow, stale response overwriting a newer one: cancellation, tokens and what a cooperative service does? 15.7.1 · L5
    An effect is asynchronous, so responses can arrive out of order: the user types “ab”, then “abc”; the “ab” request is slower and lands last, and the screen…
  2. How do you model screen state so illegal combinations cannot exist: enum with payloads versus a bag of flags? 15.7.2 · L3
    A screen modelled as isLoading: Bool, items: [Item]? and error: String? has 2 × 2 × 2 = 8 combinations, and several are nonsense: loading and failed at once…

Composition

Child reducers inside parents.

  1. How do you compose reducers: child features inside a parent, scoping state with key paths and embedding actions? 15.7.3 · L5
    A real app is a tree of features, and each should be written and tested alone. Composition has two parts. Scoping state: a child reducer works on its own small…

More in Architecture & API design