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({
...