October 23, 2019
Sometimes in react your view is dependent on a api call, and need to display a loading icon as you wait for the api.
Here is a snippet of code I use to accoplish this:
// example
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Loading from './loading';
export default class Example extends Component {
constructor(props) {
super(props);
this.state = {
loading: true,
}
}
componentDidMount() {
setTimeout(() => {
this.setState({ loading: false });
}, 5000);
}
render() {
return (
<Loading>
example
</Loading>
);
}
}
// loading.js
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import './loading.scss'
class Loading extends Component {
constructor(props) {
super(props);
this.spinner = this.spinner.bind(this);
}
spinner() {
if (this.props.loading) {
return (
<div className="loading">
<svg version="1.1" id="loader-1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
width="100px" height="100px" viewBox="0 0 40 40" enableBackground="new 0 0 40 40">
<path opacity="0.2" fill="#000" d="M20.201,5.169c-8.254,0-14.946,6.692-14.946,14.946c0,8.255,6.692,14.946,14.946,14.946
s14.946-6.691,14.946-14.946C35.146,11.861,28.455,5.169,20.201,5.169z M20.201,31.749c-6.425,0-11.634-5.208-11.634-11.634
c0-6.425,5.209-11.634,11.634-11.634c6.425,0,11.633,5.209,11.633,11.634C31.834,26.541,26.626,31.749,20.201,31.749z"/>
<path fill="#000" d="M26.013,10.047l1.654-2.866c-2.198-1.272-4.743-2.012-7.466-2.012h0v3.312h0
C22.32,8.481,24.301,9.057,26.013,10.047z">
<animateTransform attributeType="xml"
attributeName="transform"
type="rotate"
from="0 20 20"
to="360 20 20"
dur="0.5s"
repeatCount="indefinite"/>
</path>
</svg>
</div>
)
}
}
render() {
if (this.props.loading) {
return this.spinner();
}
return this.props.children;
}
}
Loading.propTypes = {
loading: PropTypes.bool.isRequired,
};
export default Loading;
loading.css
:
.loading {
display: flex;
align-items: center;
justify-content: center;
padding: 100px 0px;
svg {
margin: 6px 10px;
path,
rect{
fill: #8ad7dd;
}
}
}