React – Redux Flow

Redux is a predictable state container for JavaScript apps. That means if you want to use something to manage state of your application you can use Redux. It can work with any modern framework like Vue, React.js or Angular.js. But it more popular with React because of its similarities with Facebooks’s Flux architecture.

Use Redux when:

  • When application is getting  more complex. Specially with data flows.
  • When components need to talk to each other.
  • Non Hierarchal data.
  • Too many actions from components.
  • Same data needed in multiple places.

 

 How Redux works with React.js :

  • React: A user action like clicking on submit button dispatches an action.
  • Action: Perform the action which is asked (it can be call to webservice to fetch date or something else). As soon as this action is completed it notifies reducer to change it state.
  • Reducers: Takes the current state and action and returns a new state. (I know this sounds complicated but its not)
  • Store: Notifies other connected components about this state change.
  • React-Redux:  New data is passed on to these components from store. Now react intelligently determine if UI need to be updated.
  • React: If react determines updated is needed in UI. New data is passed via prop from the store and UI re-renders.

Key Components in Redux:

Actions:

Actions are used to transporting data from UI to store. You can use store.dispatch() to send data from UI to store. Action are plain javascript objects which must have a type property indicating type of action that needs to be performed.

Example:    You can view full file here

export function createCourseSuccess(course) {
  return {type: types.CREATE_COURSE_SUCCESS, course};
}

Action can be also used for calling a web-service or call to database or any computation logic.

Example:

Call the actions directly from UI or when your application using dispatch like this :

store.dispatch(loadCourses());
export function loadCourses() {
  return function(dispatch) {
    dispatch(beginAjaxCall());
    return courseApi.getAllCourses().then(courses => {
      dispatch(loadCoursesSuccess(courses));
    }).catch(error => {
      throw(error);
    });
  };
}
export function loadCoursesSuccess(courses) {
  return { type: types.LOAD_COURSES_SUCCESS, courses};
}

 

Reducers

Reducers are used for changing the state of the application. They take action as state as input and return new state.

For example: You can view the full file here.

export default function courseReducer(state = initialState.courses, action) {
  switch (action.type) {

    case types.CREATE_COURSE_SUCCESS:
      return [
        ...state,
        Object.assign({}, action.course)
      ];

    default:
      return state;
  }
}

Object.assign is new way in ES6 to make deep copy of object. Read more here.

Store:

Store is the single source of truth for your application. It holds the state of the application.

Example:  You can view the full code here.

This is the boilerplate code to glue reducers and initial state together.

export default function configureStore(initialState) {
  return createStore(
    rootReducer,
    initialState,
    applyMiddleware(thunk, reduxImmutableStateInvariant())
  );
}

Use dispatch action (Link to source code) :

const store = configureStore();
store.dispatch(loadCourses());
store.dispatch(loadAuthors());

render(
  <Provider store={store}>
    <Router history={browserHistory} routes={routes} />
  </Provider>,
  document.getElementById('app')
);

Connect:

Connect is a library that connect react components to redux store.

Link to source code:

import {connect} from 'react-redux';

function mapStateToProps(state, ownProps) {
 return {
 courses: state.courses
 };
}

function mapDispatchToProps(dispatch) {
 return {
 actions: bindActionCreators(courseActions, dispatch)
 };
}

export default connect(mapStateToProps, mapDispatchToProps)(CoursesPage);

[mapStateToProps(state, [ownProps]): stateProps] (Function): If specified, the component will subscribe to Redux store updates. Any time it updates, mapStateToProps will be called. Its result must be a plain object*, and it will be merged into the component’s props. If you omit it, the component will not be subscribed to the Redux store.

If ownProps is specified as a second argument, its value will be the props passed to your component, and mapStateToProps will be additionally re-invoked whenever the component receives new props (e.g. if props received from a parent component have shallowly changed, and you use the ownProps argument, mapStateToProps is re-evaluated).

[mapDispatchToProps(dispatch, [ownProps]): dispatchProps] (Object or Function): If an object is passed, each function inside it will be assumed to be a Redux action creator. An object with the same function names, but with every action creator wrapped into a dispatch call so they may be invoked directly, will be merged into the component’s props. If a function is passed, it will be given dispatch. It’s up to you to return an object that somehow uses dispatch to bind action creators in your own way. (Tip: you may use the bindActionCreators()helper from Redux.) If you omit it, the default implementation just injects dispatch into your component’s props. If ownProps is specified as a second argument, its value will be the props passed to your component, and mapDispatchToProps will be re-invoked whenever the component receives new props.

 

Full React-Redux project is available here.

References:

http://redux.js.org/

https://github.com/reactjs/react-redux

Cory House http://www.reactjsconsulting.com/

 

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