Dissecting Redux (Part 1)

Redux act as an architecture for the React library. It improves Flux whereas Flux improves common MV* pattern used among lots of client-side frameworks like Angular.

While MV* pattern usually went for two-way data binding, where both model and view can simultaneously change one another, Redux doesn’t work that way.

It leverages React’s unidirectional flow (parent-child one direction data flow), therefore makes your code easier to reason about, especially when your codebase goes large.

There are several main ideas on Redux:

  • It isolate I/O and data fetching
  • One source of truth (state)
  • Only state can change the view
  • Immutability

Instead of old-fashion event-driven sourcing, Redux (and Flux) wraps an event as an action, plain object which describe the type and correspond data. It enables I/O and data fetching response to not directly alter your view. It queues as an action.

So, whenever a button is clicked, user type into a text box, or data from server received, an action is dispatched. Any component can also dispatch an action.

That action will be received by the dispatcher and pass to something called as the reducer. What a reducer does is it handles your state. It may or may not changes your state. It receives both an action and previous state, then returns a new state.


View –> Action –> Dispatch –> Reducers –> View

Any React component (View) can dispatch any action, which will be received by the dispatcher, then it will be passed to the reducer which will change your state. Any changes to your state will be reflected to your View (UI).

Always keep in mind that your View is a reflection of your state. Ideally, your View will re-renders every time the state changes.


createStore() implementation

const createStore = (reducer) => {  
  let state;
  let listener = [];
  const getState = () => state;
  const dispatch = (action) => {
    state = reducer(state, action);
    listeners.forEach(listener => listener());
  }
  const subscribe = (listener) => {
    listeners.push(listener);
    return () => {
      listeners = listeners.filter(l => l !== listener);
    };
  };
  dispatch({});
  return {
    getState,
    dispatch,
    subscribe,
  };
};

The code might not look exactly as above, but the idea stays the same.

The store leverages factory to make store instances, and make use of closure. So instances return from createStore() will have a .getState() ,dispatch() , and subscribe()  functions.

By closure means that even though createStore() function has popped/exited, it’s variable environment (meaning all variables created inside the function scope) will not be thrown away (by garbage collector) and still accessible by any execution context (function) generated inside the createStore().

.getState() is a getter to get your current state.

.dispatch() is the method which will handle your dispatching need. It receives an action, and will pass that same action to the reducer. The reducer will generates a new state that will be re-assigned to the state.

.subscribe() defines what you’d like to do after your state changes. It pushes a function to the listener array where that array will be iterated at the end of the dispatch function.

Notice that there is an empty action triggered by dispatch({}) at the bottom (although it will pass something different now)? The idea is to trigger default argument in the reducer, so you can specify an initial state for your store.

We’ll continue several implementation on the next part.

Pokemon Bot App

A Pokemon illegal app that I designed for noob trainers. Is not intended for any gym battles.

Features

Enables you to quickly jump around illegally with your Pokemon account only by entering your username, password, and coordinates on the web.

This app is no longer working nor maintained since a major update by Niantic.

I built it using React and Redux as the front-end layer, and Node.js as the backend.

pokemon-bot-app

Behind the scene

React turns out to be a really brilliant library. And Redux just made your life way easier by improving over Flux. These architecture design totally surpasses common MV* model.

In my opinion, although most people would say that React is more declarative than Angular (which I believe so too), but it seems that Angular massive codebase just makes it looks more vague in terms of how they actually build the framework. This puts Angular to an ‘abstract’ condition since I totally have no clue on how they build the framework (or probably just too lazy to find out).

Anyway,

Once you switch to React/Redux, you’ll never go back (to Angular).