[React_Redux] Redux?

When working with React components, it is critical to have the standardized way to handle the data flow. Flux was popular with React but Redux becomes more popular.

 

1. Why Redux?

React is about the structure and Redux is data flow.
  •  Redux is useful to handle complex data flows (inter-component (non-hierarchical) communications)
  • Same data can be used in multiple places

 

2. Redux – 3 Principles

  • One immutable store
  • User actions are done through Actions
  • State is changed by pure functions (Reducers)

 

3. Redux Flow

  • One way (unidirectional) flow
  • Single store with hierarchical (nested) reducers
  • Actions -> Reducers -> Store -> React

 

4. Actions

An action is a way to initiate the change of the existing state.
  •  Action is a plain object of “type” and data.
  • Action Creator returns an action object.
  • When an action is dispatched by a Store, reducers will handle the data and update the store.
let doSomething = (data) => {
  return {
    type: 'ACTION_NAME',
    data: data
  }
};

 

5. Store

In Redux, “Store” and “Change logic” are separate.
  •  Only One store
  •  Immutable
let store = createStore(reducer, initialState, enhancer);
Once you have a store, you can do the followings:
store.dispatch(action)
store.subscribe(listener)
store.getState()
Note that there is NO “setState()” in Store. The only way to update the store is through dispatching the actions (and reducers).

 

6. Immutability

To change state, a new state object must be returned. (A state object cannot be modified.)

In ES2015, you can use the following techniques:

  • Object.assign(target, …source)
  • Spread operator
let newState = Object.assign({}, oldState, {data: newValue});
let newState = { ...oldState, data: newValue };

The biggest benefit of immutable objects in Redux is the logic how to check the state has been modified. By replacing the state object rather than by modifying existing one, Redux can just compare the old state and the new state using the equality operator. It is a big performance boost.

if (previousStoreState !== storeState) {
}

Also you can just save the state history just by saving all state objects.

 

7. Reducers

A Reducer is a pure function to returns a new state.
  • Accepts the current state and action
  • Create a new updated state
  • Returns the new state oject -> Store is updated

All Reducers are called on each action dispatch.

  • switch statement and default (return the old state) are the common pattern
As a pure function, a Reducer
  • May not mutate arguments
  • May not perform any side-effect
  • May not call any non-pure functions
const myReducer = (state, action) => {
  switch(action.type) {
    case 'ACTION_NAME':
      return Object.assign({}, state, {data: action.data});
    default:
      return state;
  }
};

 

8. Root Reducer

Rather than creating one giant reducer with dozens of case statement, you might want to create many small reducers.

It is a quite common pattern that you combine all reducers in a single reducer (Root reducer) and provide this root reducer to the store.

import { combineReducers } from 'redux';

export default rootReducers = combineReducers({
  categoryList: categoryReducers.categoryListReducer,
  categoryCreate: categoryReducers.categoryCreateReducer,
  directorList: directorReducers.directorListReducer
});

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s