9/29/16

Redux - the blitz

I have heard a lot about redux but never had time to put my hands on it., so i guess the time is come - lets write something about redux.

So, what is redux?

To put the long terms short - it is a way to organize logic which changes the state (application data) of single page application. So if you asking yourself: is redux about to make me write less code? - Well, the answer is no, this is not the point. The point is - to make clear for developer who and why changed the state of app.

Three Basic Principles Of Redux

According to what the documentation say, three basic principles of redux are:
1. Single source of truth( single store )
2. State is read-only
3. Changes are made with pure functions (reducers)
For implementing the redux into our search app we will use react-redux library.

Lets Talk About Three Primary Modules Of React-Redux

Store

Most important module there all application data (or state) is stored:
initial state:


export default {
    results: [],
    loading: false
}

...
...
...
const rootReducer = combineReducers({
  results: searchResults,
  loading
});

export default rootReducer;

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

Actions

A way by which components can "talk" with store, explaining what exactly gonna happen.
search action:


export function loadResultsSuccess(results) {
  return { type: 'LOAD_RESULTS_SUCCESS', results};
}

export function loadResults(query) {
  return function(dispatch) {
     let url = "https://api.github.com/search/repositories?q="+query+"+language:typescript&sort=stars&order=desc";
     
     return  fetch(url)
        .then(function(response) {
         return response.json();
        })
        .then((result) => {
            let results;
            if (result.items.length !== 0) { 
               results = result.items.slice(0,5);
            } else {
               results = [];
            }
            //DISPATCH RESULTS
            dispatch(loadResultsSuccess(results));
        });
  };
}

Reducers

Should get the info from action and return new state object which generated from the original state, but without mutating it.


import initialState from './initialState';

export default function searchReducer(state = initialState.results, action) {
  switch (action.type) {
    case 'LOAD_RESULTS_SUCCESS':
      return action.results;

    default:
      return state;
  }
}

Make The Appllication To Work With Stuff Was Just Created

Lest modify our SearchPage so, it will dispatch "search" action instead of calling "loadResults" method (which duty was to load the search results from the request and put the to the state):
SearchPage component:


import React, { Component, PropTypes } from 'react'
import SearchBar from './mySearchBar';
import ResultsList from './myResultsList';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import * as searchActions from './actions/actionSearch';

class SearchPage extends Component {
      constructor(props) {
        super(props)
      }

      handleSearchTextChange(txt) {
        this.props.loadResults(txt);//<---HERE      
      }

      render() {
        const {results, loading} = this.props;
       
        return (
          <div>
            <SearchBar onChange={this.handleSearchTextChange.bind(this)}/>
            <ResultsList results={results} loading={loading}/>
          </div>
        );
      }
};
    

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

function mapDispatchToProps(dispatch) {
  return {
    loadResults: bindActionCreators(searchActions.loadResults, dispatch)
  };
}

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

See the full code on the repo

Getting started with docker

It is very simple to get started usig docker. All you need to do-is download the docker desktop for your system Once you get docker syste...