Demo for Displaying a loading message while initializing a React component

See https://disjoint.ca/til/2017/10/09/displaying-a-loading-message-while-initializing-a-react-component for details. author(s): Marvin Pinto

HTML

<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.7.2/redux.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/5.0.6/react-redux.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux-thunk/2.2.0/redux-thunk.js"></script>
<div id="container"></div>

CSS

html,
body {
  display: flex;
  min-height: 100vh;
  min-width: 100vw;
  background: white;
}

#container {
  display: flex;
  flex: 1 1 auto;
  justify-content: center;
  align-items: center;
}

.loading-container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.spinner {
  width: 40px;
  height: 40px;
  position: relative;
}

.double-bounce1,
.double-bounce2 {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background-color: #333;
  opacity: 0.6;
  position: absolute;
  top: 0;
  left: 0;

  -webkit-animation: sk-bounce 2s infinite ease-in-out;
  animation: sk-bounce 2s infinite ease-in-out;
}

.double-bounce2 {
  -webkit-animation-delay: -1s;
  animation-delay: -1s;
}

@-webkit-keyframes sk-bounce {
  0%,
  100% {
    -webkit-transform: scale(0);
  }
  50% {
    -webkit-transform: scale(1);
  }
}

@keyframes sk-bounce {
  0%,
  100% {
    transform: scale(0);
    -webkit-transform: scale(0);
  }
  50% {
    transform: scale(1);
    -webkit-transform: scale(1);
  }
}

Babel + JSX

const { Provider, connect } = ReactRedux;
const { createStore, applyMiddleware } = Redux;
const thunk = ReduxThunk.default;

const sleep = time => {
  return new Promise(resolve => setTimeout(resolve, time));
};

//============
// Reducer
//============
const defaultState = {
  isRefreshingSettings: false,
  isRetrievingToken: false,
  appToken: null
};

const reducer = (state = defaultState, action) => {
  switch (action.type) {
    case "MAKE_REFRESH_SETTINGS_REQUEST":
      return {
        ...state,
        isRefreshingSettings: true
      };
    case "RECEIVE_REFRESH_SETTINGS_RESULT":
      return {
        ...state,
        isRefreshingSettings: false
      };
    case "MAKE_RETRIEVE_TOKEN_REQUEST":
      return {
        ...state,
        isRetrievingToken: true
      };
    case "RECEIVE_RETRIEVE_TOKEN_RESULT":
      return {
        ...state,
        isRetrievingToken: false,
        appToken: action.result
      };
    default:
      return state;
  }
};

//============
// Actions
//============
const initiateRefreshSettingsRequest = () => {
  return dispatch =>
    Promise.resolve().then(() => {
      dispatch({ type: "MAKE_REFRESH_SETTINGS_REQUEST" });
      return Promise.resolve()
        .then(() => {
          return sleep(600);
        })
        .then(() => {
          dispatch({ type: "RECEIVE_REFRESH_SETTINGS_RESULT" });
        })
        .catch(error => {
          dispatch({ type: "RECEIVE_REFRESH_SETTINGS_RESULT" });
          throw error;
        });
    });
};

const initiateRetrieveTokenRequest = () => {
  return dispatch =>
    Promise.resolve().then(() => {
      dispatch({ type: "MAKE_RETRIEVE_TOKEN_REQUEST" });
      return Promise.resolve()
        .then(() => {
          return sleep(600);
        })
        .then(() => {
          dispatch({
            type: "RECEIVE_RETRIEVE_TOKEN_RESULT",
            result: "SECRETTOKEN"
          });
          return "SECRETTOKEN";
        })
        .catch(error => {
          dispatch({
  ...