by Bob MacNeal, 28 August 2019
Over React’s brief history, one challenge has been application state management.
Unlike first-generation web applications that served web pages via requests and responses off of specific state-describing routes, React single page applications (SPAs) typically don’t use much deep linking. More often, an entire React SPA exists within ― and is described by ― a few explicit routes.
Managing component-level state and application-level state has been a burr under the React developer’s saddle.
Component-level state are potentially changing properties that are only needed within a component (e.g., a boolean property indicating to show or hide a message depending on the user’s input).
Application-level state are the potentially changing properties that other components might care about. For example, given a widgets list component and a create widget component, the widgets list component should care when a widget has been created so it can render an updated list.
Iteration One: Props Drilling
In React days of yore, prop drilling was used to maintain and share the state of potentially updatable properties. With prop drilling, we passed (or drilled down) properties and functions to each child in the component tree.
Prop drilling works well, but it’s tedious, often untidy, and can be risky without explicit type checking.
Iteration Two: State Containers
Enter popular state containers like react-redux and MobX. Now developers need not rely solely on prop drilling because predictable, scalable, state management had arrived as an appendage to React, albeit with odd-looking connect syntax required to wire up state sharing with react-redux.
State containers are industrial-strength state management. However, they can be cumbersome, are sometimes inscrutable during troubleshooting, and typically require boilerplate code.
Bad habits ensued with state containers. Chief among the anti-patterns I observed is that that developers tended to stuff all of their state into redux, even local state which other components did not care about.
Iteration Three: Hooks
React state management now has several options. I find React’s useState and useContext hooks are simpler and less cumbersome than react-redux.
Of course there’s no one-size-fits-all with state management. One’s approach should always be guided by pragmatism.
“Keep state as local as possible and use context only when prop drilling really becomes a problem. Doing things this way will make it easier for you to maintain state interactions.”Application State Management With React
– Kent C. Dodds
For me there’s a tension between the purpose served and the resistance to implementation. I’m reminded of an Extreme Programming mantra:
“Do the simplest thing that could possibly work.”Extreme Programming Pocket Guide, Chromatic
Application State Management With React, Kent C. Dodds;
Prop Drilling, Kent C. Dodds;