I'll show you how I went about it, but I would love feedback. Is there a better way to do this?
Leave a comment or shoot me an email at jason.melton2@gmail.com
.
Preliminary Junk
I set up a create-react-app
, deleted a bunch of default stuff, and a file structure like this:
I added some basic CSS to the App component — height, width, and a flex box to center all its contents.
I also set up a json file containing the data that I will map into Count components.
Count Component
The object of my Count component is to accept some data about how the count should run and render the animation.
First, I set up a basic component.
Count gets props of a data item from data.json. I destructured the label
, number
, and duration
from the props.
Using JSX, I return the label
and number
as a header. Later, I will change number
so that it animates, but for now I can style the hard-coded version of what I'm building.
Increment Function
I'm going to set up a function that increments from 0 to the desired number in these three steps.
- Set up a
useState
hook that saves our display number and, when updated, will trigger a render of the component.
The hook looks like this:
I update the JSX to display count
instead of number
.
- Set up a
useEffect
hook that calculates the count and increment time.
useEffect()
firstly takes an anonymous function that will handle the count. I create variables start
and end
. start
is set to 0.
Initially, I used number
as my end
. However, I realized, for very large numbers, a better method would be use to increment only the first three digits of number
and paste the the rest back on before updating the count. This way the counter won't take all night.
I calculate the rate of each increment by dividing the duration (seconds) by the number of increments I plan on doing and multiply by 1000 to convert to milliseconds.
Initially, I was hoping to speed up the interval to make up for large numbers, but
setInterval()
has a minimum duration of 10 milliseconds. Any number less than 10 will reset back to 10.
- In that same
useEffect
hook, I employsetInterval()
to increment the count with side effect of re-rendering the component.
I add one to start
and call setCount()
to update my useState
hook. I convert start
to a string and, if it's a large number, I concat the rest of the number that I previously chopped off.
The entire component will now look like this:
Conclusion
I read through several articles about this sort of animation and combined their ideas with my instinct to make the abstract reusable component above.
I am not sure what I came up with is the best method. For example setInterval
had limitations I didn't foresee. I would love some feedback. Feel free to shoot me an email at jason.melton2@gmail.com
.
Best, Jason