Some tips for getting started with Redux
About a month ago I wrote an article providing some tips for getting started with React. I’ve recently been looking into Redux and thought it might be useful to provide a few tips that I picked up along the way.
None of this is really new information but should reinforce messages that you’ve already heard elsewhere.
Don’t look at Redux until you’re comfortable with React
I’ve seen this stated many times before and I’m so glad that I didn’t dive into Redux straight away. In fact I would recommend that you don’t even start using Redux until you recognise that you have a problem that you can’t easily solve with React by itself.
In my case I was building some components for complex forms and found that I the data flow between the form and field components was becoming increasingly complex. This prompted me to look at Redux as a way of solving the problem and I found that it greatly simplified everything.
So don’t use it unless you need it, but more importantly make sure it actually helps when you start using it.
Watch Dan Abramov’s Course on egghead.io
Even if you’re not interested in learning Redux I’d still recommend that you watch this course. Not only does it brilliantly explain Redux but it provides some awesome concrete examples of where you can effectively use ES6 capabilities.
It takes quite a while to get through but is definitely worth investing the time to do so. I can’t recommend this course highly enough.
If you’re not into TDD (Test Driven Development) then now would be a good time to start. When I started my Redux project it was the first time that I’d truly done TDD (in that I genuinely wrote the tests before I wrote the code to be tested). It helps that writing reducer functions lends itself to TDD but I found that having a solid body of tests implemented meant that I avoided going down any rabbit holes as I got further into my project.
I found that in taking this approach I’d almost written all of my reducers before I even started on my components and as a result both the writing and testing of my components was trivial.
It just felt like so much additional boilerplate code to write and I was sure that it would be more efficient to handle dispatching and subscribing myself (although apparently connect does provide lots of optimizations).
What I did find though was that I was able to implement my own re-usable function to define common PropTypes, mapStateToProps and mapDispatchToProps and then call connect. This greatly reduced the amount of code I needed in my field components as they all shared common Redux behaviour (although this approach only makes sense in this type of scenario — you wouldn’t want to be connecting things that use the Redux store differently with the same connect calls).
Dispatching functions are in props
This is very minor thing but did briefly catch me out. In most of the examples the React components are simple rendering functions (and this is actually one of the great things about using Redux is that it can massively simplify what you need to build in React) and as such the dispatch functions are passed in as arguments to the function.
However, when you’re writing a component class you need to access the dispatch functions through this.props. I got caught on this because I had a dispatch function with the same name as an instance function of my component.
Use Higher Order Components
I did find that in some cases I wanted to provide default values when they weren’t provided as props. It’s not possible to mutate the props within the constructor of a React component however you can work around this problem with the use of Higher Order Components. This allows you to pass sensible defaults into your components when none are provided.
This enabled me to solve a problem where I wanted to generate an identifier if one wasn’t provided that would be passed to Redux. If I allowed the reducer to generate the identifier then it would not be possible to map the component to the appropriate state in the store. Using a higher order component enabled me to pass a generated identifier into the component to be enhanced so that the identify was available in props throughout its life-cycle.