Actually you do, it’s just that if you’re new to React JS development, it’s another big thing to learn.
Wait, who says not to use Redux?
Everyone talks about Redux, most React developers use it, and yet if you search for articles to help you decide if it’s right for you, you’ll find things like:
Redux Vs Component State… Why? It’s all about creating a pattern so that you and your coworkers know where to put data(state) as your app grows. Some examples of state: AJAX response data(which user is logged in?) Is the page loading? has it loaded? How many seconds have passed since this component has rendered?
People often choose Redux before they need it. “What if our app doesn’t scale without it?” Later, developers frown at the indirection Redux introduced to their code. “Why do I have to touch three files to get a simple feature working?” Why indeed!
That last one is actually from Dan Abramov, the creator of Redux, who doesn’t recommend that React developers always reach for Redux. Here he is again on Twitter:
Good thread. Don’t use Redux unless you *tried* local component state and were dissatisfied. https://t.co/MR3XWsdhd1
— Dan Abramov (@dan_abramov) April 26, 2016
So, it sounds a bit like the recommendation is to try your new React app without Redux first, and when things get complex enough and you’re feeling the pain that it’s intended to address, you slot it in.
What is state management anyway?
The whole point of React is that data only ever flows in one direction. Your components have data available to them (somehow), and they use it in their presentation logic, and pass some of it to child components.
This is what makes React so easy to learn. Initially at least, it looks exactly like the templates you might use in a server-side rendered application.
However, data does of course need to change. For example, in our child widget there might be a button the user presses, causing a change in the data.
So where does this changeable data go? React provides a place for it that you can use, which is the “state” of any component. In the above case, the data storage in question could be in the state object of the parent. Any component can have state, but not everything component should. Some important rules of thumb are:
- If you component has a bunch of state logic and a bunch of rendering logic, split it into two components. This lets you use the presentational (dumb) component in new situations (and also in tests).
- Don’t put state in every single component, if you do use this system, put state at important parts of the component hierarchy.
What’s the pain point here?
When storing state in components, there’s a tension between two extremes. If you put state in a lot of small components, then those components are less tied to the rest of the application, and are more like mini applications of their own that can be re-used independently. If you put state in fewer and fewer places in a large component tree, you end up passing lots of data down the tree and the whole tree tends to end up knowing a lot about your application.
In that paragraph, the independent components sounds like the better option, but it’s not an approach that you will have a chance to use very often. It’s very common that multiple parts of your interface need access to the same data. Duplicating that data in two different data stores is a horrible idea that will cause many bad things to happen and I trust you’d never do that.
Since it’s more likely that you’re going to need to re-use state across many components on the page, it becomes important how tightly bound they are to the shape of that state.
How does Redux help?
Redux picks a side. It says that there is a single data store, so that all your state is in one place. It goes on to reduce the extent to which you have to keep passing this around by providing a way for you to connect parts of that state directly into parts of the component tree rather than always manually passing it down.
If you’ve heard anything about Redux though, you’ll know that it picks sides in a few other battles as well. In particular it says that state is immutable, and that to “change” it you need to raise an action, which is handled asynchronously and used to produce a new state from the old state. This is a form of Command Query Responsibility Segregation, and allows your component code to focus on what events are occurring without coupling that to how the state change works.
This all means that Redux introduces more layers of indirection when it comes to writing the code that you need right now to make your button press do something. Redux makes simple problems a bit more complex, and complex ones more predictable and simple.
At best, adding Redux to the mix will just make all the learning feel that much more onerous, at words, you’ll write bad code full of half-understood boilerplate.
So, take Dan Abramov’s advice, don’t use Redux until you have tried local component state and been dissatisfied.
Once you have though, you’re going to find that, like me, you’ll include Redux in your new projects from day one. Good use of Redux makes a React app much simpler to reason about, and in particular it makes it much easier to work with libraries and external services that want to have some effect on the state of your application.
Quick wins when you’re using Redux
There are are a huge number of them, but here are a few quick examples.
Persist some or all of your state between page loads
You almost never want to make the user do everything from scratch if they hit refresh in their browser. Some of that state data needs to be stored in the browser, on the phone, or wherever your client lives. Don’t roll this yourself, just install:
redux-persist – persist and rehydrate a redux store
Handle URL routing in the same was as any other user action
Oh my god, stop messing around with all those other complicated routing libraries. Actions that change the state are simple, do routing in exactly the same way. Get great places to load data at the same time.
redux-first-router – 🎖 seamless redux-first routing — just dispatch actions
Avoid API lock in, use GraphQL
Changing client app requirements, multiple versions or multiple platforms can cause your API to become a graveyard for mistakes you can’t change. GraphQL is designed to solve that problem, and due to it’s self-documenting nature, it can actually be a lot more fun to use than regular Restful APIs. Facebook’s own code to use graphql is complicated, opinionated and very hard to learn. The Apollo project, which uses Redux under the hood, is easy to get started with, and has great documentation and community involvement.
Make forms easy again
Several years of work by Rails and other server side frameworks finally made it easy and predictable to build forms with validation, and all the other features you’d expect. When we switched to thicker client development, it got hard again. If you find yourself writing your own low level code that says things like “if this password value is less than 8 characters then make this text box red and disable submit”, then you’re doing it wrong, just grab:
The best way to manage your form state in Redux.
How and when to take the plunge
You’re going to find it easiest to use Redux in a greenfield app. It’s not the only way to do so, it can be quite safe and easy to refactor from local component state to Redux, but it’s advisable to at least try a Redux out in a fresh application to see how everything works.
After that, here are a few random bits of advice:
- Keep the boilerplate low initially. Don’t write action creators or define constants for your action types. Have a read through the this page on boilerplate.
- Get the Redux dev-tools working immediately, and keep them open while you code to learn how everything works.
- Use Flow or TypeScript from your Redux related code. The two work particularly well together to help you refactor fast in this area. More detail in my article on type checking.
As you start to work with Redux, you’ll see common patterns repeating as you remove duplication in your code, and perhaps you’ll have some favorite approaches or libraries to make things even nice. I’d love to hear which ones work best for you.