The Law of the instrument originates from the quote:
I suppose it is tempting, if the only tool you have is a hammer, to treat everything as if it were a nail.
This is a favourite of mine, as it is surprising how often I have seen people use the wrong tool for the wrong job, or try and adapt it for work that it was not originally intended to do.
The Shiny New Toy
A recent example at home is our air fryer: we have thrown a lot into it, with pretty mixed results! The trouble is: when you have a shiny new toy, you often try and use it for almost anything, rather than keeping to the use cases for which it works best.
I've seen a few examples of this in software engineering — particularly SQL databases — but by far the most common recent problem has been the widespread misuse of Redux. Naturally, this starts with only good intentions: a single source of truth for the entire state of an application. However, this seems to have morphed into storing virtually everything and anything in that state. The biggest problem by far has been its misuse as a caching mechanism, leading to frustrating problems with outdated information, which led my team to completely overhaul and massively reduce our state management.
Why Do We Need this Anyway?
Let's take the problem of caching data: is a cache even required in the first place? How do you know it is needed? Are data fetches really that slow?
When my team switched to GraphQL, fetches have been incredibly specific and suited just to the needs of the current user interface, so most fetches are fast enough for us (under 100 milliseconds). Showing the most recent information at the time of rendering a UI - and sometimes refreshing with real-time websocket requests - is actually of benefit to the business, so managing a UI cache is unnecessary.
What About Time Travel?
A very neat feature of Redux is time travel: the ability to see all the changes to the state in sequence, which can help understand user journeys and locate problems. However, decent Application Performance Management tools such as Sentry give you even more information, such as the details of the browser and HTML elements used. Some packages also push every single tiny change to Redux — I didn't need to see every keypress Redux Forms! — so, anecdotally, Sentry has been far more useful.
Surely All State Should be Centralised?
State that is specific to a particular UI element or section does not need to be stored in Redux! Local state, particularly using React hooks, is usually far simpler treated as ephemeral, rather than polluting or bloating a centralised store. Good unit testing and component isolation are indicators as to whether your local storage should be hoisted up to Redux, or often, whether the UI itself needs simplifying.
Should I Bother With Redux at All?
Absolutely! Used well, just like any tool, Redux is incredibly useful, particularly for navigation and common settings. Brilliantly, other great tools improve its Developer Experience: I highly recommend immer and typesafe-actions. React hooks has again greatly simplified usage.
Discover Another Awesome Tool!
As I discussed recently, there are plenty of brilliant open-source packages that solve (most?) common problems, so if the one you are using is struggling to solve your particular issue: stop and take a look around. Recently, it took me around an hour to find and evaluate the aforementioned typesafe-actions, but it enabled us to better unit-test our state and wipe out one-third of the unnecessary type declarations. Best of all: it was fun.