React.js and Redux

Okay. It’s official now. This has to be the week when I have said the most “I don’t understand this” ever in my life. But, this was also the week when I had the most “Aha!” moments in my head on finally getting a hang of things.

TIP: Do not get carried away by the fancy words and the syntax. The concept underneath is pretty awesome and easy to understand.

So, let’s get this started!
React-Redux. Lennon-McCartney. Mario-Luigi. Sherlock-Watson. Rosencrantz-Guildenstern. Pikachu-Charizard. You get it, right? They work best in combination.

Okay, so let’s look at React first.

WHAT IS REACT?

React is a JavaScript library built at Facebook with one aim: building large applications with data that changes over time. It allows us to express what our application would look like at any given point in time; it updates the view.

React is responsible for automatically managing the UI every time some data changes, which is conceptually equivalent to hitting a Refresh button.

React is all about building components, which are nothing pieces of JavaScript that returns a component’s tree. Using React, we just build reusable components which makes testing and separation of concerns easy. But that’s all it does, renders HTML.

The most interesting concept of React is the Virtual DOM. React renders a virtual DOM modeled around the real DOM by mirroring DOM’s current state. React is very smart. So when the virtual DOM changes, React takes only these changes to modify the DOM rather than rebuilding it from the ground up.
It does so by:
– running a ‘diffing’ algorithm to see what the changes are, and then
– updating the DOM with the result of diff.

COMPONENTS

Components are user developed JavaScript objects which represent HTML elements. They contain both the structure and functionality,
basically all the things user can see and respond to on the screen, and are without a doubt the bread and butter of React.

PROPS

When we use our defined components, we can add attributes called props. These attributes are available in our component as this.props and can be used to render dynamic data. Props can be used for passing data from a parent to a child which can be seen as a communication channel between different components.

STATE

State is best defined as how a component’s data & UI looks at a given point in time. State holds data which can change over time. It contains data that a component’s event handlers may change to trigger a UI update.

 WORK FLOW

  • React render a component with an initial state.
  • Change of state when some UI update happens, like say a button is clicked.
  • React re-renders the component to the virtual DOM
  • The new virtual DOM is compared with the previous virtual DOM
  • React isolates what has changed and updates the browser DOM


To sum up: whenever a component’s state is updated, React renders a new UI based on this new state and takes care of updating the DOM for us in the most efficient way.
That’s all great, but
who handles other things like actually updating the component’s state? Who deals with the state, and it’s logic? Well, this is where our buddy Redux comes in!

 

WHAT IS REDUX?

Redux is a “predictable state container for JavaScript appswith minimal API. It is a library that maintains the application state in one place, that lets the application know how to respond and modify a state when some action is triggered. And since it is not rendering anything, it weighs practically nothing.

What Redux offers us:
– A single store.
– Action and Action-creators
– A single rootReducer (composed of one or more Reducers)
– A single, over-simplified great life.

ACTIONS

Everything that happens, that changes something in our app, is an “action”. These can be caused by users, browser events, or server events. Every action must have an action.type and the rest is data.

Action Creators: These are function that, well, create actions. 🙂

export function newMessage(message) {
  return {type: MESSAGE_RECEIVED, message};
}

We dispatch these actions to the store using store.dispatch(newMessage(event.data))

But what happens when we need to perform multiple actions one after the other or when an action actually triggers multiple modifications?
That’s where redux-saga comes in the play but we will investigate that later 🙂

REDUCER

Reducers process the action and computes new states. The reducers has access to the current state, applies the given action to that state, and returns a new desired state.

const INITIAL_STATE = {
  messages: [],
  subscription: {},
};

export function blog(state = INITIAL_STATE, action) {
  switch (action.type) {
//this returns a brand new state after concatenating new message to the list
    case MESSAGE_RECEIVED: {
      return {...state, messages: [...state.messages, {
        date: new Date().toString(),
        text: action.message
      }]};
    }
    default: {
      return state;
    }
  }
}

NOTE:

  • The reducers are passed only the slice of current state that requires updating.
  • Reducers are pure functions. They just calculate a new state from the information given to them, it must not produce any side effects like API calls or routing transitions.
  • Remember: Your app’s state is immutable. That is why, reducers don’t modify the existing state, they compute and construct a separate piece of state which is formed using the data from the action: oldState + action = newState.
  • We return the previous state in the default case, for any unknown action.
  • For complex app, we may have multiple reducers managing their own slices of the global state, but all of them must be combined under a single rootReducer using combineReducers().
import { combineReducers } from 'redux'

const rootReducer = combineReducers({
  blog,
  //other reducers
});

All the returned states from different reducers are composed together to form the complete state of the application.

This is the beauty of Redux, any time an object is changed, we replace it, instead of editing it in place. It makes things a lot simpler and faster.

Also, the really awesome part about this concept is, since we are creating new states every time some changes occur, if we were to log out the actions that resulted in these new states, we could essentially be “time-traveling” back to the exact old state we were at, before those actions actually happened. If this isn’t magical, I don’t know what is. 🙂

magic

STORE

The whole state of your app is stored in an object tree inside a single store. This is the part of Redux that brings the action and reducers together. The store listens for actions, and uses the root reducer to return a new app state each time an action is dispatched. This complete new state, of course, goes into a single store.

const store = configureStore({
  blog: {
    messages: [{
      date: new Date().toString(),
      text: "App starting up"
    }]
  }
});

WRAP UP!

To sum it up, Redux provides predictable ways of maintaining our application’s state in one place. When we pair this with React, we get the complete package. We can now, not only change the state appropriately (Redux’s thing) but also view our automatically updated state without reloading the page. (React thing). Awesome, right? 🙂

Told you they complete each other.

Oh, one more. Winnie the Pooh and Christopher Robin!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s