Functional reactive programming (FRP) describes a program with just two ideas: events, which happen at a moment, and behaviors, which change over time. Everything else is derived from them with pure functions, and that keeps a program easy to reason about as it grows.
Introduction to FRP, the next lesson, sets out its key concepts: events and behaviors, state as a fold, declarative code, immutable data and event-driven code. The principles below are how the team builds them.
Key principles
-
Events as actions: Each event is a plain action object named for what happened, such as
orderPlaced, whether a person, a timer or the server caused it; the sequence of dispatched actions is the application’s event stream. -
Subscriptions: A React view subscribes to the store through
useAppSelector, and an RTK Query hook subscribes to a cached request; both end when the view unmounts, so none is managed by hand. -
Selectors:
createSelectorcomposes small pure functions into derived values, the way FRP derives one behavior from another, and recomputes a value only when its inputs change. - Event handling: A reducer handles each event in one place, as a pure step from one state to the next; listener middleware handles what must follow it, such as a later request; and a view’s handler only dispatches.
FRP in practice
In custom apps, the Sean Dinwiddie’s Webmastery team builds FRP’s ideas in Redux Toolkit, and Introduction to FRP traces where they come from: actions are the events, reducers fold them into state, and selectors derive the values a view shows. The lecture Redux Standard Patterns and Functional Programming traces that one-way dataflow, from event to reducer to selector to view.
Benefits of FRP
- Reactive: A view reads values derived from state and shows the new ones when they change, so no code has to remember to refresh it.
- Composability: A selector is built from smaller selectors and a function from smaller functions, so a new value reuses the ones the module already trusts.
- Readability: Each value is defined once, so a reader finds the cart’s total in one selector rather than in every handler that touches the cart.
- Testability: Reducers and selectors are pure, so a test is a list of actions and the result expected, with no browser or server.
- Maintainability: A new event is a new case in each reducer that responds to it, and a new value a new selector, so each change lands where its test runs.
FRP comes down to events, a fold and the values derived from it: in Redux Toolkit, actions, a reducer and selectors, with every effect kept at the edge. The lessons in this module take each in turn, and Module 4 carries one feature from its user story and scenarios through its state to a typed API, and on to launch.