Thursday, 24 June 2021

Using request animation frame in React

I'm reading this article and I'm not sure I understand how the final hook works.

Here is the code:

const useAnimationFrame = (callback) => {
  const requestRef = useRef();
  const previousTimeRef = useRef();

  const animate = (time) => {
    if (previousTimeRef.current !== undefined) {
      const deltaTime = time - previousTimeRef.current;
      callback(deltaTime);
    }
    previousTimeRef.current = time;
    requestRef.current = requestAnimationFrame(animate);
  };

  useEffect(() => {
    requestRef.current = requestAnimationFrame(animate);
    return () => cancelAnimationFrame(requestRef.current);
  }, []);
}

and used for example in this way:

const [count, setCount] = useState(0);

useAnimationFrame((deltaTime) => {
  setCount((prevCount) => {
    return prevCount + 1;
  });
});

Ok, the goal is have a number value that is incremented every frame.

I can explain what is happens running this code:

  1. the component create a local state with useState(0)

  2. then the useAnimationFrame hook is called using this callback as parameter:

    (deltaTime) => {
      setCount((prevCount) => {
        return prevCount + 1;
      });
    }
    

the function takes a number as input and increment ste state value of one each time it is called.

  1. useAnimationFrame is a function that takes another function as a parameter (a callback). It creates two refs. At the first time it is executed (because of the []) it calls the useEffect. It saves in requestRef.current the timestamp the requestAnimationFrame returns. The requestRef.current calls the animate function that computes the delta time between the request animation frames (the previous and the current) and then call the callback with this value so it calls the setCount. Then it updates the current refs values and recall the requestAnimationFrame.

So the cycle should be:

component 
  > count = 0
useAnimationFrame             <--------------+
  > requestRef = ?                           |
  > previousTimeRef = ?                      |
    useEffect                                |
      animate                                |
        > deltaTime = delta#1                |
        > count = 1                          |
        > previousTimeRef.current = time#1   |
        > requestRef.current = time#2 -------+
      > requestRef.current = timestamp#1

Am I wrong?



from Using request animation frame in React

No comments:

Post a Comment