skip to Main Content
  const movingRef = useRef(false);

  const handleStartMove = (e) => {
    movingRef.current = true;

    e.stopPropagation();
    // handleMove doesn't take the latest value if we use a state instead of a ref
    document.addEventListener('mousemove', handleMove);
    if (onMoveStart) {
      onMoveStart(e, movingRef.current, angle);
    }

  };

  const handleMove = (e) => {
    e.stopPropagation();
    e.preventDefault();

    if (!movingRef.current) {
      return;
    }
    this.moveDOMElement(e);
  };

I have something like this and I noticed if I replaced movingRef = useRef(false) with const [moving, setMoving] = useState(false), it doesn’t work. It works with refs and I read that useRef changes propagate faster since the callback function "handleMove" takes the cached value of the setState variable moving (or state), instead of taking the latest value, but if you use ref you will always use the latest value. Is this the case?

I heard that this is a closure-related behavior and using a state variable causes synchronization and side effect issues while using refs allows us to avoid that and get what we would expect.

2

Answers


    • Use useRef when the value has does not need the component to re-render. The .current value of a ref is a variable that you control, updating it does not tell React to re-render.

    • useState is for values that should queue a re-render. When you call the setX returned by useState, React queues a re-render and the value will be the updated one on the next render. This is mentioned in useState‘s caveats:

    The set function only updates the state variable for the next render. If you read the state variable after calling the set function, you will still get the old value that was on the screen before your call.

    From the limited code you posted it looks like movingRef is not referenced in the template, updating it does not need a re-render, and so useRef is a good choice.

    Login or Signup to reply.
  1. Yes, when you are using useState the set state is asynchronous. So it will not update the state immediately.
    useRef gives you a mutable object. the movingRef gives you the most recent value and can be updated directly.
    In your context, the useState may not update quickly for the mousemove event, so it’s better to use useRef since it’s mutable and not tied to the component’s render cycle.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search