Tips & Tricks for your React-Redux Application 👌

Please note: This assumes you are familiar with the flow of React & Redux. We are using the redux-saga middleware in our example. The focus of this article is more about boilerplate and not styling.

If you are accustomed to building React applications with Redux, you’ll know there is a lot of associated boilerplate. When implementing a feature, it usually involves the following steps.

  1. Build a component and determine the state/data that is needed for our component to function correctly.
  2. Once we have the state we need, we map our Component’s state to props passed from the store.
  3. To get that state — in our case it’s a collection of users — we’ll need to call an API endpoint provided from the backend guys. This means we need to trigger an action with a dispatch in our Component.
  4. Our Redux saga middleware listens for this action and then makes a request to our API service to fetch the users when the action has been fired.
  5. When the saga has finished making the call and it was successful, it will trigger an effect with a new success action. The reducer will then update the store with the people list. The Component is now aware of the change of props and will re-render with the new state retrieved.

We created a simple create-react-app for this ‘People’ application. It will render a list of people. Simplez… (Try to make the sound the meerkat makes on the adverts but fail miserably).

We added a Header and Panel component, but our focus is on a component called PeopleList that will just render an array of people to the browser. While we are waiting for the data from the API, we’ll show a loading animation.

Please note: We structure our components in the following way.

src/components/Component/Component.js
src/components/Component/Component.css
src/components/Component/index.js

This allows us to break apart the connection with Redux and test the component in isolation. Now onto the component implementation.

src/components/PeopleList/PeopleList.js

Now we connect it to redux in the index file.

components/PeopleList/index.js

Next thing we will do is define our action types.

export const GET_PEOPLE = 'GET_PEOPLE';

Now usually we would define an action type for each state of a request when making an API call. Like so:

export const GET_PEOPLE = 'GET_PEOPLE';
export const GET_PEOPLE_REQUEST = 'GET_PEOPLE_REQUEST';
export const GET_PEOPLE_FAILURE = 'GET_PEOPLE_FAILURE';
export const GET_PEOPLE_SUCCESS = 'GET_PEOPLE_SUCCESS';

Then in the reducer, we’d usually define a switch case for each of these action types.

switch (action.type)
case GET_PEOPLE_REQUEST:
... update state
case GET_PEOPLE_FAILURE:
... update state
case GET_PEOPLE_SUCCESS:
... update state with users

We can make use of redux-saga-routines to simplify this boilerplate, by doing the following.

Please note: In your own application you will need to
npm install redux-saga-routines

src/actions/index.js

Now getPeople will be an object that has all of these states. So we can simply import the routine alone instead of multiple action types.

src/reducers/people.js

The problem with having a large switch case in your reducers like above is that you may have issues with redeclaring variables or constants in the same lexical scope. The linter could also complain as you do to that neighbour with the dog that won’t stop barking all night.

Dog sorry about barking

We can make use of something called handleActions that will give each action its own lexical scope to avoid clashing with the other actions.

Please note: In your own application you will need to
npm install redux-actions

src/reducers/people.js (New version)

Now we have cleaned up our reducer and action, we can check out our saga. You can see below we import the getPeople routine, and it has a function called success and failure. At the bottom, you can see we are listening for a REQUEST, and then firing the getPeopleRequest generator function which in turn calls the service and gets us back the data we need.

src/sagas/people.js

The API service is simply calling a Fake API on the web. Here it is for clarity.

src/services/api.js

The service below injects axios (The library used to make HTTP requests) through the constructor. This makes it much easier to mock in unit tests. This is an approach known as dependency injection.

When I run the application, I see my redux saga routine in action and the store being updated using the Redux Dev tools.

Hope you enjoyed reading along. The source code for this project can be found here. Please drop a few claps if you enjoyed and leave feedback or any questions you may have. Thanks!

Redux Saga Routines
Redux Actions

Shaun Michael Stone.
Follow and reach out to me on Twitter.