<div id="app"></div>
const useAnimationFrame = (isRunning, callback = () => {}) => {
const reqIdRef = React.useRef();
const loop = React.useCallback(() => {
if (isRunning) {
reqIdRef.current = requestAnimationFrame(loop);
callback();
}
}, [isRunning, callback]);
React.useEffect(() => {
reqIdRef.current = requestAnimationFrame(loop);
return () => cancelAnimationFrame(reqIdRef.current);
}, [loop]);
};
const Component = () => {
const [counter, setCounter] = React.useState(0);
const [isRunning, setIsRunning] = React.useState(false);
const countUp = React.useCallback(() => {
setCounter(prevCount => ++prevCount);
});
useAnimationFrame(isRunning, countUp);
return (
<div>
<div>{counter}</div>
<button onClick={() => setIsRunning(true)}>START</button>
<button onClick={() => setIsRunning(false)}>STOP</button>
</div>
);
};
const App = () => {
return (
<div>
<Component />
</div>
);
}
ReactDOM.render(<App />, document.getElementById('app'));
View Compiled
This Pen doesn't use any external CSS resources.