Elm architecture with React + Redux + Redux-loop

2018/8/1 posted in  Node.js

https://smallbusinessforum.co/elm-architecture-with-react-redux-redux-loop-645a67070b1a

When I started learning React I have beed so confused with Flux architecture. I understand problem which Flux trying to solve, but i don’t have a clue how to do it properly.

After playing with Facebook Flux implementation it was good for me but i wanted to write less boilerplate code with different stores. I made my own implementation of stores with connection to dispatcher updates, but it still wasn’t looks perfect.

After while i discovered this great presentation by Dan Abramav

I were so excited about single atom of state and how Redux transparent looks Redux flow. It was so easy for development and I started my next project on work with React + Redux.

As for many developers one question wasn’t clear enough with this tools.

How to solve side effects like http requests

Elm

I were plunged into background of Redux and found Elm. After learning some basics I understand that it is what I’m looking for. But Elm looks so hardcore for production development and I just made a few simple projects at home.

This code demonstrate how easy Elm deal with side effects and extracts them from main business logic, like it never exists in your application.

The update function now returns more than just a new model. It returns a new model and some commands you want to run. These commands are all going to produce Msg values that will get fed right back into our update function.

There is a subscriptions function. This function lets you declare any event sources you need to subscribe to given the current model. Just like with Html Msg and Cmd Msg, these subscriptions will produce Msg values that get fed right back into our update function.

One crucial detail here is that commands and subscriptions are data. When you create a command, you do not actually do it. Same with commands in real life. Point is, commands and subscriptions are data. You hand them to Elm to actually run them, giving Elm a chance to log all of this information.

This application flow looks so easy and transparent that i started to search similar way in React+Redux ecosystem.

Many methods for handling effects in Redux, especially those implemented with action-creators, incorrectly teach the user that asynchronous effects are fundamentally different from synchronous state transitions. This separation encourages divergent and increasingly specific means of processing particular types effects. Instead, we should focus on making our reducers powerful enough to handle asynchronous effects as well as synchronous state transitions.

Redux-thunk

Redux Thunk middleware allows you to write action creators that return a function instead of an action. The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met. The inner function receives the store methods dispatch and getState as parameters.

Problem of thunk that inside this function you could do any what you want and never handle whats going wrong. You don’t have description of effects which need to be run.

Redux-saga

Next thing that I found was Redux-saga. It helps you to separate side-effects from your application, but made it more complex because actions now used in another parts of your application where you keep your sagas. So I not been satisfied at all and continue searching.

redux-saga is a library that aims to make side effects (i.e. asynchronous things like data fetching and impure things like accessing the browser cache) in React/Redux applications easier and better.

The mental model is that a saga is like a separate thread in your application that’s solely responsible for side effects. redux-saga is a redux middleware, which means this thread can be started, paused and cancelled from the main application with normal redux actions, it has access to the full redux application state and it can dispatch redux actions as well.

Redux-loop

Final catch was the best I found not popular library Redux-loop. It solve side-effect problem in a way that I prefer.

After every state update it next effects needed to be run described in your state. The values returned from the reducer when scheduling an effect with redux-loop only describe the effect. Calling the reducer will not cause the effect to run. The value returned by the reducer is just an object that the store knows how to interpret when it is enhanced by redux-loop. You can safely call a reducer in your tests without worrying about waiting for effects to finish and what they will do to your environment.

With redux-loop, the reducer doesn't just decide what happens now due to a particular action, it decides what happens next. All of the behavior of your application can be traced through one place, and that behavior can be easily broken apart and composed back together. This is one of the most powerful features of the Elm architecture, and with redux-loop it is a feature of Redux as well.

When I started my product Recomea redux-loop become my best friend to handle side-effects.

...
case SIGN_IN_FACEBOOK:
  return loop(        
   state,        
   Effects.promise(         
    facebookSigninEffect,       
   )      
);
...

With reducers like this all my components become more clear and I forgot about horrible redux-thunk.