Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
Aquasar

Animating a number counter with React Hooks

Recommended Posts

I am trying to create this simple example https://codepen.io/GreenSock/pen/hzfji 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>
  );
};

 

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×