We use cookies and other tracking technologies to improve your browsing experience on our site, analyze site traffic, and understand where our audience is coming from. To find out more, please read our privacy policy.

By choosing 'I Accept', you consent to our use of cookies and other tracking technologies.

We use cookies and other tracking technologies to improve your browsing experience on our site, analyze site traffic, and understand where our audience is coming from. To find out more, please read our privacy policy.

By choosing 'I Accept', you consent to our use of cookies and other tracking technologies. Less

We use cookies and other tracking technologies... More

Login or register
to apply for this job!

Login or register
to save this job!

Login or register to start contributing with an article!

Login or register
to see more jobs from this company!

Login or register
to boost this post!

Show some love to the author of this blog by giving their post some rocket fuel 🚀.

Login or register to search for your ideal job!

Login or register to start working on this issue!

Engineers who find a new job through JavaScript Works average a 15% increase in salary 🚀

Blog hero image

A scalable dataflow technique for your Redux apps

Mike Vercoelen 25 January, 2018 | 3 min read

In this article you’ll learn how to setup a scalable, simple and consistent technique for your dataflow in your Redux apps.

  logo-title-dark 1.png  

So you’ve created some stuff for the interwebs with React and Redux, super great, awesome well done. Maybe you’ve even created an app that has some users: even more awesome.

I’ve been there and after working on a few projects that had over 100k lines of code frontend wise, I found myself struggling with handling data in Redux in a scalable and consistent way.

I’ve tried ducks and numerous of other ways of getting it right. When I landed in a complex e-commerce platform, me and my frontend besties discussed and discussed and came up with a solution: the entities reducer.

The entities reducer

So let’s talk about the entities reducer, see it as a mini database for your frontend app. It’s a place where all the data of your application lives. All queries and modifications will be in one place, so you and your team will know exactly where to look for handling data.

The best way of explaining the entities reducer is by example. Let’s dive right in.

The example we are using will be a chat application, thinking about a chat application what kind of data “entities” do we have:

  • Users
  • Rooms
  • Messages

Now you can imagine where the name “entities” comes from.

There are a few dependencies that are optional, but used throughout all the examples in this article. I highly recommended them for managing your data.

  • Immutable.js – This will give you a clean API for querying your data and can even offer performance benefits
  • Normalizr – Flatten your data structures, we don’t want nested entities. Everything should be flattened.Let’s start with creating an empty entities reducer.

entities.js

import { fromJS } from 'immutable'

// TODO: you should put this in your `utils`, and make a helper, so you can reuse this because it's awesome
function createReducer (initialState, handlers) {
  return function reducer (state = initialState, action) {
    if (handlers.hasOwnProperty(action.type)) {
      return handlers[action.type](state, action)
    }

    return state
  }
}

// The chat application has: `users`, `rooms` and `messages` as data entities
// We use `fromJS` to make it an immutable object
export const initialState = fromJS({
  users: {},
  rooms: {},
  messages: {}
})

export default createReducer(initialState, {
  // The reducer will go here...
})

Now what kind of actions do we have in our mega awesome chat app? 
  • Login
  • Logout
  • Create room
  • Join room
  • Send message
  • Receive message

Just imagine these actions working, by using thunk or sagas. It does not matter for this article how they work, just pretend they work and get triggered.

IMPORTANT NOTE: All the actions should have a payload created by normalizr

So remember: by using this technique, all the data of your application will be in ONE place only. So all actions that do something with your data, should also be handled in this reducer.

First we need to add the following helper function to our fresh new entities reducer. This helper function will help us easily set data on our entities reducer.

const mergeEntities = (state, { payload }) => {
  return state.withMutations(state =>
    Object.keys(payload.entities).reduce(
      (_state, entity) => _state.mergeDeepIn([entity], payload.entities[entity]),
      state
    )
  )
}

If you take a good look at mergeEntities you can see that it basically handles an action for us, the first argument is the state, and the second destructs the payload from an action.

If you take an even closer look: you can see it accesses payload.entities this comes from using normalizr


Mike's Website @mikevercoelen
If you're interested in working with React.js full time, check out all of our React jobs here on the job board!

Related Issues

viebel / klipse-clj
viebel / klipse-clj
  • Open
  • 0
  • 0
  • Intermediate
  • Clojure
viebel / klipse
  • Open
  • 0
  • 0
  • Intermediate
  • Clojure
viebel / klipse
  • 1
  • 0
  • Intermediate
  • Clojure
viebel / klipse
  • Started
  • 0
  • 1
  • Intermediate
  • Clojure
  • $80
viebel / klipse
  • Open
  • 0
  • 0
  • Advanced
  • Clojure
  • $80
viebel / klipse
  • Started
  • 0
  • 2
  • Advanced
  • Clojure
  • $180
viebel / klipse
  • Started
  • 0
  • 1
  • Intermediate
  • Clojure
viebel / klipse
  • 1
  • 1
  • Advanced
  • Clojure
  • $300

Get hired!

Sign up now and apply for roles at companies that interest you.

Engineers who find a new job through JavaScript Works average a 15% increase in salary.

Start with GithubStart with Stack OverflowStart with Email