Why Redux is not so easy, some alternatives

React with Redux is probably the most popular front-end framework in this year. Redux is great and has changed architecture of front-end apps. If you are looking for new job, you probably will find some interesting offers with Angular 1.x, Angular 2 and others, but most interesting are about React & Redux.

The choice for a lot of programmers is quite obvious, but we should consider some cons of using Redux:

  1. It’s not easy to switch to work with reducers
  2. Don’t Repeat Yourself
  3. Care about performance — render()

You will need to care about functional principles and always return new value based on previous state. Sometimes it’s easy (simple string, objects or array operations) as:

return {…previousObject, newValue: value}

but for more complex changes you probably would like to use Immutable.js or similar library.

During the work on large application you will need to think about combine reducers, higher-order reducers, separate UI and data states, handle errors in your async requests (redux-thunk, redux-promise — libraries for manage async actions) and build some abstract layer (for computations) by eg. reselect library. You need to also remember, that data in your reducer should be normalized and would be better to have those data as flat as possible — check normalizr library.

I recommend gitbook Redux without profanity to check, how author try to solve problems of Redux state management:

Working with Redux needs to keep some conventions, as create actions types, actions (action creators) and reducers.

For similar logic as CRUD operations (synchro with server) your Redux code maybe will look very similar (isLoading state, errors handling, Map() or List() with your data from response etc.). Adding small functionality will need from you adding a lot of redux logic + tests. You will think probably about refactoring to follow DRY rule.

Maybe good choice will be to create something like a abstract layer / API for Redux flow to avoid writing similar code for CRUD operations on your models.

In the end what we really want to have is a single source of truth which is easy in maintain, and which trigger smallest changes in DOM structure as possible.

During work on React application you need to care, that what you pass by props are the new data, because they will rerender whole component. Sometimes you will want to prevent render (by shouldComponentUpdate method) and maybe use pure render mixin to check that data is really changed (you can also use React.PureComponent since React 15.3).

In more complicated data structure Immutable.js library is really helpful, because it operates on references to objects (your store is an Immutable.js tree of references to smaller Immutable.js data). You can imagine situation, when very nested component use small part of your store. You have changed another part of store which is not used directly by your nested component. Immutable.js will prevent unnecessary rendering because component will have reference to the same object in his property.

There are some rules which you need to keep in mind when you work with Immutable.js in React. Those rules are not very obvious for new developer, as do not trigger toJS() method before injecting data to your props. Using Immutable.js in wrong way very often doesn’t give you a lot of benefits. Eg. toJS() method always create new object, so it triggers unnecessary rendering when you pass it by property.

This article is a must to read before you start developing with Immutable.js:

It’s not easy to create large application (I am no talking about simple TODO app) without using bunch of libraries. It’s great, that around React/Redux there is a large community which develop amazing tools like Redux Saga, React Router, Redux Form etc.

If you check how many libraries I have mentioned in this article, you will realize that React & Redux stack is a NOT just a simple framework and the entry threshold is big especially for junior developer.

Some alternatives

State management with Redux is predictable but is not easy to learn and not fast to write. There are some alternatives, libraries which make your work much easier:

  1. MobX
  2. Relay/Apollo & GraphQL
  3. Jumpsuit
  4. Helpers / generators, as conventional-redux.js

This new library has a lot of solutions for mentioned problems and I recommend to try it. It is based on 3 points: state, derivations and actions. Thanks to getters and setters synchronization between models and UI is automagic.

Render() method of component is triggered only when data are observed and used in your component. You can check this relation by dependency tree in DevTools plugin. I like idea of Michel Weststrate, who is author of MobX, that setState in your component should be used only for UI changes -> React is a view layer.

Thanks to MobX you can back to OOP and use some methods directly on your models item, eg. product.addToCart(). You don’t need to normalize your objects (which should be done if you use Redux store).

More about MobX you will read in this article:

If you like idea of MobX I recommend start learning with Egghead.io free coruse. It has also really nice documentation.

Relay & GraphQL stack is not so new, as you could think that it is, but is not so popular as Redux. It is developed by Facebook and described as framework for building data-driven react applications: https://facebook.github.io/relay/.

There are a lot of benefits of using Relay with GraphQL. The biggest one is that you can forget (from frontend perspective) about how you should fetch data to get correct response for entities used in view (what endpoint with what params you need to use etc.). Relay with GraphQL makes it for you. All what you need to do, is to prepare special GraphQL request (which is something like a JSON without values) in container. Your REST requests logic could be kept for example in Node.js proxy server which will be something like a communication layer between frontend and backend.

Here is a good article which compares Redux and Relay:

If you are interested in this area, you should also read about Falcor (equivalent GraphQL from Netflix): https://netflix.github.io/falcor/starter/what-is-falcor.html and Apollo (GraphQL client from guys who develops Meteor).

Thanks to Apollo you don’t need to replace Redux by Relay to use GraphQL:

In my opinion Apollo or Relay with GraphQL should become much more popular in the end of this year and possible in 2017.

This is a solution for someone, who doesn’t like MobX, but pure Redux is tiresome. Jumpsuit is a framework based on Redux which makes your flow more automatic. If you don’t like to build application from scratch (mean adding & configuring a lot of packages), use Jumpuit, which gives you also simplified API layer for React and Redux.

More benefits of using Jumpuit you will find in this article:

It has currently more that 1K stars on github, so maybe you should consider use it before start new project.

One of the biggest problem with Redux app is a lot of code duplications. I have mentioned it in the beginning of this article (Do Not Repeat Yourself). Conventional-redux.js is an interesting approach to simplify your workflow.

This is dedicated for specific problems, so maybe won’t be the solution in your project. But might inspire you to write something similar. Create abstract layer on similar redux logic will save your time in future (also on writing tests). I recommend to check source code on github to know how people try to solve their problems.

Jumpsuit and Conventional-redux.js (and a lot of other similar tools) tries to improve your Redux workflow. They are good choice for someone (or for team) who is familiar with Redux, probably has prepared a lot of data/state logic and don’t want to write this again or/and put more effort in learning curve.

MobX and Relay & GraphQL goes outside of Redux stack (but you can still use GraphQL with Redux thanks to Apollo!). MobX is quite easy to learn and in management. I recommend it if you want to write something from scratch really quickly. GraphQL needs a lot of time to build backend data flow logic, but after fronted implementation should be much easier.

Full-stack developer - react.js, node.js, serverless. @machnicki

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store