Newer Post

React Baby Steps III: Idiomatic Redux

Older Post

React Baby Steps

React Baby Steps II: The First Taste of Redux

After React Baby Steps, it was time to learn Redux. Yes, because it’s popular, but also because I’ve found that my React Redux-free app has one top component propagating props to the leaves of the component tree. So components in between, even if they don’t need some props, have to receive them just to propagate them down. Redux manages state and allows us to access it from any level in the component tree.

After some basic courses, even if straightforward, I had to bang my head one whole day (and night) to be able to refactor a plain React app to a Redux version properly. That’s why this early article on my Redux learning path, to summarize and share my findings. Here you can find my first Redux version of the app.

Note: Redux can be used without React, but I am assuming React-Redux usage.

Learning Resources

Presentational and Container Components

It’s important to understand this topic. Presentational components already have data and handlers provided via props, so they can only worry how to render data and call provided functions. Container components are opposite – they are not concerned about UI, they provide data and business logic for presentational components.

In Redux we create container components with the connect function by providing data and behavior which in return gives us higher order components to enhance our component. That way, the enhanced component will automatically have everything without worrying about how to get it. If you check my app here, you can find presentational components in the components folder and container components in the containers folder. There is no strict rule on how to do it. For example, the App component is a container. It prepares the initial state and provides some data for the presentational component below (ReactCountries). Thus, ReactCountries is a presentational component that uses some props to render. The callback doesn’t have any business logic and has both presentational and container components inside. Other container components inside are preparing things relevant to different parts of the application (toolbar, list, add dialog, etc.). That way, we don’t have to propagate everything from the top but rather introduce containers where it makes sense to provide data for the underlying presentational component.

I highly recommend Thinking in React; it will help you understand this topic and structure your React app properly. Don’t worry; it takes some time to get it.

Project Structure

project structure

State, Reducers and Actions

One of the first things you will do in a Redux app is to think about state/reducer organization and actions. Each reducer has its own corresponding part of the state object it is responsible for and is not able to access other parts of the state. There is no strict rule here. For example, I have 3 reducers: countries (managing an array of user’s countries), allCountries (managing the DB of all countries) and ui (managing various parts of the UI state like filters, visibility flags, messages, etc.). Check Dissecting Twitter’s Redux Store to get an overview of how smart guys design their store.

For now, I feel that it makes sense to keep logic in reducers and make actions thin.

Preparing State Data in Container Components

In a pure React app when you need to prepare some data (using an API/DB for example) in the state, you can easily do it in the componentDidMount lifecycle method of the top component (it has access to this.state). But in a Redux app, the state is not managed by React anymore, and I’ve lost some time to realize how to do it, although it’s straightforward. The problem is that you don’t have access to dispatch from lifecycle methods, so I didn’t know how to store data in the state when ready. If you take a look at the App container component, you will see that the solution is to add fetching logic in mapDispatchToProps, where you have access to dispatch, then to enhance the current container component using connect (and not the underlying presentational component) so that it can access this.props.someFetchingMethod from componentDidMount. and then just to render the underlying presentational component, passing down the required props.

Accessing State Data from Reducers

Sometimes you will need to access some state data from a reducer that doesn’t have access to it, as it manages another part of the state. My current solution for this is to pass required state data down as props to the component that will, in the end, invoke a handler and pass the data back to the action creator, which will pack data in an action and thus make it available to any reducer.

Dispatch Chaining

I am not sure what the proper terminology is, but I’ve stumbled upon this problem – let’s say I dispatch one action, there is some logic going on in the reducer, and depending on some condition(s), I may want to invoke another/second dispatch. Example: 1) save something to the DB and 2) if successful – show a message. With my current (basic) level of knowledge, I am not aware of how to do it.

Next Steps

Conclusion

At first, I was sure that Redux is simple because it only has to manage the state. Then, I realized it has many components but seems logical. However, when I tried to apply it, I had more questions than answers and had the impression that it’s too complex and difficult. Finally, I made the transition from pure React to a Redux app, and it looks OK. A little bit more complex, with more files and code, and more time consuming, but it is giving me hope and motivation to continue with more advanced topics and witness the real power of it.

We'll help you unleash.

Join the 30,000 developers who subscribe to our newsletter.

Scale your
Development team

We help you execute projects by providing trusted developers who can join your team and immediately start delivering high-quality code.

Hire Developers
code, react, redux