P.Brian.Mackey P.Brian.Mackey - 7 months ago 43
jQuery Question

Create a loading animation that works in react


var Hello = React.createClass({
getInitialState: function() {
return {
gridIsLoaded: true

animate(self) {
$('#loadingDiv').animate({'opacity': '0'}, 500, function(){
$('#loadingDiv').animate({'opacity': '.5'}, 500, function(){
$('#loadingDiv').animate({'opacity': '1'}, 500, function(){

getData() {
console.log('getData called.');
var artificialTimeout = 5000;
var self = this;


complete: function (response) {
setTimeout(function() {
self.setState({gridIsLoaded: true});
}, artificialTimeout);

error: function () {
console.log('there was an error!');
self.setState({gridIsLoaded: true});
return false;

this.setState({gridIsLoaded: false});

render: function() {
var loadingJsx;
if (!this.state.gridIsLoaded) {
loadingJsx = (
<div id="loadingDiv" style={{ position:'relative', 'width': '100%', 'textAlign': 'center'}} className="text-center">
Loading... please wait

return <div>
<input type="button" value="Submit" onClick={this.handleClick} />

<Hello name="World" />,

When I click submit this says "Loading please wait..." as it should. I want the opacity to animate in and out while loading is displayed. That is not working. Then if I click submit again it should do the same thing.

How can I get the animation to work?

Simple case outside react works.


A more 'react' way to do this would be to toggle a class on an element when you want to animate it. So in this case, we can conditionally apply an animate class when the grid has not loaded (though it's redundant in this case as that's the only time it shows).

loadingJsx = (
  <div id="loadingDiv" className={this.state.gridIsLoaded ? 'text-center' : 'text-center animate'}>
    Loading... please wait

Then I've separated out the css to apply to #loadingDiv.animate, though an alternate approach would be to toggle a style object. I suppose you could also continuously update the opacity property of a style object, which is closer to what you're doing, but it seems dirtier imo.

#loadingDiv.animate {
  opacity: 0;
  animation: fadeInOut 1s infinite;

@keyframes fadeInOut {
  0% { opacity: 0; }
  50% { opacity: 1; }
  100% { opacity: 0; }

updated fiddle