Vanja's Blog

Subscribe to Blog via Email


Enter your email address to subscribe and receive notifications of new posts by email.

Social


Recent Posts


Top Posts & Pages


Categories


Tags


Share


Idiomatic Redux

Deep Dive into Redux 🔮

Vanja PetreskiVanja Petreski

After First Taste of Redux I did Building React Applications with Idiomatic Redux course. You can find notes and source code (branch per lesson) for it. Here is my React Countries app source code, refactored with new knowledge. You can see how it looks.

API

Now we have fake API simulating backend with all operations and data encapsulated there. Fetching countries, adding, removing, updating, it’s all there. All methods return Promises and have delay (500ms), so that it feels like real backend. In user countries fetching logic I’ve introduced probability of 50% to get an error, to simulate error handling.

Colocating Selectors

I’ve introduced, so called, colocating selectors in reducers, these are just methods, usually simple getters, for getting some part of the state. Each reducer is responsible for providing its part of the state, so you will frequently see delegating between reducers. So now, components don’t have to know anything about the state shape, they just call selectors providing the state and get what they need. With this approach we can refactor our reducers and state shape without modifying components at all.

Normalizing the State Shape

It’s important to normalize the state shape, so that part of it looks more like a database. Read this article for more information. I am currently not using Normalizr, but it’s good idea when you have normalized state and data from the server are complex/nested. Tool helps you to normalize data from the server, so that you can apply it directly to your state.

Middleware

By default, when you dispatch an action, it’s a simple object with type and other information and its nature is synchronous. It immediately reaches reducers. But what if you want to plug in some logic in between, so that you can do something after action dispatching and before reaching reducers? Middleware! When you create Redux store, you can pass an array of middlewares to be applied. For example, I am using redux-logger, redux-promise and redux-thunk middlewares in my app. Logger middleware is cross-cutting thing – on every action it logs the state before, action and the state after, in development environment, so that’s really convenient for debugging. If you want to dispatch some action in async manner, so that you can reach reducer once promise is resolved – there is no way to do it by default. Fortunately, you can use promise middleware that will enhance Redux to support promises. Like that, you can dispatch a Promise resolving a simple action object. Promise middleware will handle the rest. Even more powerful is Thunk middleware, in this case you dispatch a function that receives dispatch and getState functions as parameters. This way you can invoke dispatch multiple times in the action, sync/async and also do it conditionally since you have access to the state object, so you can receive anything from the state, without passing the data around. Alternative to Thunk is Saga middleware which seems to be more powerful, but probably more difficult to understand/learn since it uses ES6 Generators.

Updating the State

In earlier version of my app I was fetching all user’s countries and then did filtering on the UI. But this doesn’t scale well because if we have a lot of data, we simply can’t fetch it all to the client. In this version of the app I am fetching only what has to be displayed on the screen and keep that in the state. If you toggle country visited filter in the toolbar, app will either fetch/keep all user’s countries or only visited ones. Other important thing – when we add/delete/update the country we now call fake API and we want to update the UI only after we get the response from the server, because that means that operation was successful, we have return data and now we can update the state.

Dispatch Chaining

In the previous article I didn’t know how to handle the case of displaying success message when some async operation is done. This is now easy with Thunk and API. In the action we simply call async operation on API and when it resolves we dispatch another action to update the UI – show the message.

Error Handling

It’s important to gracefully handle error messages. For example, when we call API, sometimes we can get errors. We can use error handler in the Promise to dispatch failure action, then reducers can receive that to maintain error messages, etc.

Architecture

OK, so let’s take a look at the big picture. In React-Redux app we have many different small pieces that work together. It sometimes feels that we have unnecessary too many files and code, but I somehow like the fact that modules are small and doing their part of the job.

Conclusion

There are so many things more to learn, like React Router, testing, Saga, etc, but it’s now already solid knowledge and it’s time to enter into real world application and face new React-Redux challenges! 😀

Software Engineer & Digital Nomad

Comments 0
There are currently no comments.