JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.0.4/redux.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/0.10.1/fetch.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.js"></script>
<div class="jumbotron">
  <div class="container">
    <h1>Redux Thunk middleware example</h1>
  </div>
</div>
<div class="container">
  <form action="" class="form form-inline row">
    <div class="form-group">
      <input type="text" placeholder="Enter github username" class="form-control" id="myInput" />
    </div>
    <button class="btn btn-primary" type="submit">load</button>
  </form>
  <div id="loading" class="row alert alert-info hide">
    <i class="fa fa-spin fa-cog"></i> ...loading repos...
  </div>
  <div class="row">
    <ul class="list-group"></ul>
  </div>
</div>

CSS

form {
  margin-bottom: 15px;
}

JavaScript

console.clear();
// Thunk middleware
// source: https://github.com/gaearon/redux-thunk/blob/master/src/index.js
function thunkMiddleware(store) {
  return function(next) {
    return function(action) {
      if (typeof action === "function") {
        return action(store.dispatch, store.getState);
      } else {
        return next(action);
      }
    }
  }
}

// Action creators
function addReposAction(jsonResult) {
  return {
    type: "ADD_TWEETS",
    repos: jsonResult
  };
}

function userChangedAction(value) {
  return {
    type: "USER_CHANGED",
    value: value
  };
}

// returns a function and will be called in the Redux-Thunk middleware
function loadReposAction() {
  return function(dispatch, getState) {
    var state = getState();
    var url = "https://api.github.com/users/" + state.user + "/repos";
    dispatch(loadingChangedAction(true));

    return fetch(url)
      .then(function(result) {
        dispatch(loadingChangedAction(false));

        if (result.status === 200) {
          return result.json();
        }

        throw "request failed";
      })
      .then(function(jsonResult) {
        dispatch(addReposAction(jsonResult));
      })
      .catch(function(err) {
        sweetAlert("Oops...", "Couldn't fetch repos for user: " + state.user, "error");
      });
  }
}

function loadingChangedAction(isLoading) {
  return {
    type: "IS_LOADING",
    isLoading: isLoading
  }
}

// Reducers
function addTweets(state, action) {
  return {
    isLoading: state.isLoading,
    user: state.user,
    repos: action.repos
  }
}

function userChanged(state, action) {
  return {
    user: action.value,
    repos: [],
    isLoading: state.isLoading
  };
}

function isLoadingChanged(state, action) {
  return {
    user: state.user,
    repos: state.repos,
    isLoading: action.isLoading
  };
}

function initialState() {
  return {
    user: "",
    repos: [],
    isLoading: false
  }
}

function rootReducer(state, action) {
  var previousState = (state ?...