Reducer Power

May 29th, 2020
react

Building the Skills

When I first started this job about 3 months ago, my only weapon for dealing with state management was useState. Even then, I wasn't exactly awesome at it. I have tried and failed to learn Redux about a million times, and beyond that, I just didn't know any other options. I had definitely been introduced to the built in hooks, useReducer and useContext, but had never used them to the extent that I am now. If it wasn't for my cohort, I would never have gone as in depth as I have now. It all started with a pretty simple reducer in our payments application. Instead of using a package like React-Router, we are using useReducer to manage the view. So, in this reducer, there are about 10 or 15 action types with statuses attached to them. If you want to proceed to another page using a button or something, the event handler would dispatch an action with the type attached to that action. In the root component, we have it set up so the view is different for every different status, so we just match up the current status with whatever component we want to show. We pass the state and dispatch around using the Context API. It's really simple, and it was a great introduction to using reducers.

react

Redux relies heavily on reducers; in fact, it is the basis of the package. Typically, you have a switch statement with different types tied to each switch, and payloads are tied to those types. I'm not going to go into a full explanation of how reducers work, but it's a little complicated at first and then gets a lot easier. Nowadays, I have the mental model in place to understand this, but when I first started this job, I was having a really hard time grasping these concepts. Practice makes perfect, though, and I've gotten plenty of that. After we implemented that simple reducer, I decided to take things to another level with this project. Most of our actual state data was being passed to the context through useState, but I wanted to change that to use a reducer instead. I could have added on to the reducer we already had, but I thought it would be better to keep these two entities separate. It's debatable whether this is correct or not, but it made sense at the time. After quite a bit of unwinding of the current system we had in place, I was able to get it to work, and it's now a lot cleaner. It's very clear now when state is being adjusted, given a dispatch statement, and it just makes sense overall. That was my first test into the realm of more complicated reducers, and even that one was fairly simple.

react native

Fast forward to today, and whenever I think about state, I'm thinking about a reducer first and I only use a different system if it doesn't make sense for a reducer. Sometimes, you only need local state in one component, so it doesn't make sense to stick that in a reducer. I have now built three of the screens for our React Native project and I have a reducer in each one of these. Potentially, we could have one central reducer, but given the size of this thing, I think it's better to keep them local to each screen. Each of these screens encompasses over 20 components, so managing state can be a bit of a hassle. I've set up Context in the root component for each of these screens and a reducer attached to it. Today, I started building the most complex one yet. In this reducer, I'm managing the view for all of the components. We have a tab navigator at the top, plus some of the components can either be in an editing state or in a viewing state, so there are about 20 different types on this reducer. In the editing views, I'm using the React Hook Form package to get the data I need and am dispatching that to a central state so I can pass it back to the viewing state. For example, one of the components shows the lead's name and spouse's name, but if you click on the edit button, you can change that information. Eventually, we will be hooking that up to a put or patch request to send back to the database, but it's better to manipulate that state within the application and send it back in the background; otherwise, the user would have to wait for it to come back to see the changed data. I started this at about noon today, and I'm trying to make it as strongly typed as I can. Because of that, I was only about halfway through when it was time to go home. Hopefully, I remember what I was doing when I get back on Monday.

Until tomorrow!

Created by Sam Thoyre, © 2019