Showing posts with label Redux. Show all posts
Showing posts with label Redux. Show all posts

Thursday, July 27, 2017

React + Redux

Last time I showed how React components use props and states which are passed down and up to reach all the app and connect everything.
Now, what if we could have the state of the whole app in a single global object?
That is what makes Redux work best with React.
For this example, I have an input that creates rows in a table. The rows can be deleted and there is an undo and redo buttons that only go one step behind/forward. Simple enough.
Let’s see how can I apply Redux for this.

Redux stores the current state of the application in a global Javascript object. This is referred as the store.

This is the first of the three core elements of Redux: the store, the actions, and the reducers.

The stored state cannot be set implicitly, it can only change by dispatching actions.
Actions are payloads of information that send data from your application to your store. They are the only source of information for the store. You send them using store.dispatch().
Actions are plain JavaScript objects. They have a type property that indicates the type of action being performed. Types are usually defined as string constants.

I identify 4 actions for this example:
  • ADD_MATCH
  • REMOVE_MATCH
  • UNDO
  • REDO

Other than types, you can use other properties to send data to the store. In this example, I send all Match data in the ADD_MATCH action as properties.
Actions have no logic. They are just signals that tell the app that something happened. The ones responsible for handling what the action does are the reducers.

Reducers receive the current state and an action and return the new state. That’s it. Nothing magical about it. Depending on the action type you take the current state and the action object and its properties to calculate the next state.
This makes for some pretty cool interactions. For this example, I save the current state as three separate objects, each of them a pseudostate of their own.
const state = {
  past: [],
  present: [],
  future: []
};
Like this, I can store the past, present and future state of the app in the store Object. Each one will have a list of the elements on the table at any given moment of the app’s life.

Once I have this, and if I manipulate it correctly, I can easily go back to a past state with an undo action and undo the undo action with a redo action. You can even bind the keys Ctrl+ Z for the dispatch undo function!

Now, every time I call the action dispatcher to create a Match I will have to store the current present state as the new past state. Then add the new Match to the current present state and save it as the new present state. The future state can not be known at this point, so I’ll have to save the new future state as empty. The same logic applies to removing a Match.

The only time I save a future action is when the undo action is called. The current present state is saved as the future state. Then the past state will be the new present state.

It may seem a bit confusing, but with a bit of practice and coding, you will be able to understand the state-time continuum of Redux!

The rest is just like last time, React components for everything. The only difference is that the main render method needs to be saved as a constant and subscribed to the Redux store object so that changes made in the state will affect all the components.

See the Pen DotaCraft React+Redux example by Ferdinand (@ferdibranch) on CodePen.
Play as much as you want!