Jump to content
Search Community

Animating a number counter with React Hooks

Aquasar test
Moderator Tag

Recommended Posts

I am trying to create this simple example here using React Hooks. I am trying to follow along as close as possible but I am having issues animating the number.

 

I have the following code snippets to define my animation

 

  const stats = { stat0 };
  const t1 = new gsap.timeline({});
  useEffect(() => {
    t1.to(stats3, {
      stat'+=12',
      roundProps'stat',
      onUpdateupdateHandler,
    });
    return t1;
  }, []);

 

 

 

And I am returning the following

 

  return (
    <Container>
      <Stat onClick={updateHandler}>
        <span className="span1">{stats.stat}K</span>
      </Stat>
      <Blurb>
        <p>Data Servers</p>
      </Blurb>
    </Container>
  );

 

 

I am expecting my number to go from 0 to 12 when I load the page or click on the component, but it is not doing anything. Not sure what I am missing.

 

 

Here is my full code

 

import React, { useEffect } from 'react';
import { gsap } from 'gsap';
 
import styled from '@emotion/styled';
 
const Container = styled.div`
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
`;
 
const Stat = styled.div`
  & span {
    font-size: 5rem;
  }
`;
 
const Blurb = styled.div`
  & p {
    text-align: center;
    opacity: 0.8;
  }
`;
 
export const OurStats1 = () => {
  const updateHandler = () => {
    console.log('I was updated');
  };
  const stats = { stat0 };
  const t1 = new gsap.timeline({});
  useEffect(() => {
    t1.to(stats3, {
      stat'+=12',
      roundProps'stat',
      onUpdateupdateHandler,
    });
    return t1;
  }, []);
  return (
    <Container>
      <Stat onClick={updateHandler}>
        <span className="span1">{stats.stat}K</span>
      </Stat>
      <Blurb>
        <p>Data Servers</p>
      </Blurb>
    </Container>
  );
};
 
export const OurStats2 = () => {
  return (
    <Container>
      <Stat>
        <span>99.97%</span>
      </Stat>
      <Blurb>
        <p>Service Uptime</p>
      </Blurb>
    </Container>
  );
};
 
export const OurStats3 = () => {
  return (
    <Container>
      <Stat>
        <span>30</span>
      </Stat>
      <Blurb>
        <p>Fortune 500 Companies</p>
      </Blurb>
    </Container>
  );
};
 
export const OurStats4 = () => {
  return (
    <Container>
      <Stat>
        <span>10M</span>
      </Stat>
      <Blurb>
        <p>Automation Workflows</p>
      </Blurb>
    </Container>
  );
};

 

See the Pen hzfji by GreenSock (@GreenSock) on CodePen

Link to comment
Share on other sites

Hey Aquasar. I recommend checking out our article on GSAP + React:

 

Here's how I might set it up (I'm not proficient in React but I know that working with classes makes it easier):

import React, {setState} from 'react';
import { gsap } from 'gsap';
 
class GSAPComponent extends React.Component {
  constructor(props) {
    super(props);
    // reference to the animation
    this.t1 = null;
    // the data
    this.stats = {stat: 0};
    this.state = {stat: this.stats.stat};
  }

  componentDidMount() {
    this.t1 = gsap.timeline({paused: true})
    .to(this.stats, {
      duration: 3,
      stat: '+=12',
      roundProps: 'stat',
      onUpdate: () => {
        this.setState({stat: this.stats.stat})
      }
    });
  }

  handleClick = () => {
    this.t1.play();
  }

  render() {
    return (
      <div>
        <div onClick={this.handleClick}>
          <span className="span1">{this.state.stat}K</span>
        </div>
        <div>
          <p>Data Servers</p>
        </div>
      </div>
    )
  }
}

export default GSAPComponent;

 

  • Like 2
Link to comment
Share on other sites

In the future, please provide a demo instead of posting code. 

 

Animating state.

 

See the Pen 7c49fd566c08b586659aae3987b5d59d by osublake (@osublake) on CodePen

 

Directly animating text inside an element. Should you do it this way? Depends. Animating state can be slow.

 

See the Pen fdadebde8f35d6d113683dfb94569a1a by osublake (@osublake) on CodePen

 

 

 

  • Like 4
Link to comment
Share on other sites

Your issue could be in the fact that you're updating the component's state and the GSAP instances are not stored in state. Blake explained here:
 

And I explained here:

I used a lot more words than Blake to explain the same thing (talk about not wasting your time, right? :D), that's why Blake's solution works. Zach's approach also is valid and truth be said up to this day, if I'm not obliged by my clients, I don't use Hooks in any React project, nothing wrong with using class components.

 

Happy Tweening!!!

  • Like 5
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...