useRafState

requestAnimationFrame 更新状态。

useRafStateuseState 具有相同的 API,但通过 requestAnimationFrame 将状态更新延迟到下一个动画帧。这将快速的状态变化(如来自鼠标或滚动事件的变化)批处理为每帧一次更新,减少不必要的重新渲染并提高高频更新的性能。

使用场景

  • 跟踪鼠标位置、滚动偏移或窗口尺寸,这些事件触发频率远高于屏幕刷新率
  • 平滑来自传感器或数据流的状态更新,这些数据产生速度快于 60fps
  • 减少任何变化非常快且主要用于视觉输出的状态的渲染开销

注意事项

  • 仅浏览器requestAnimationFrame 在 SSR 期间不可用。hook 仍然可以工作,但更新不会在服务端被批处理。
  • 与 useState 相同的 API:返回的元组是 [state, setState],具有相同的 SetStateAction<S> 签名,因此是直接替换。
  • 自动清理:待处理的动画帧请求在卸载时被取消以防止内存泄漏。

Usage

Live Editor

function Demo() {
  const [state, setState] = useRafState({ x: 0, y: 0 });

  useMount(() => {
    const onMouseMove = (event: MouseEvent) => {
      setState({ x: event.clientX, y: event.clientY });
    };
    const onTouchMove = (event: TouchEvent) => {
      setState({
        x: event.changedTouches[0].clientX,
        y: event.changedTouches[0].clientY,
      });
    };

    document.addEventListener("mousemove", onMouseMove);
    document.addEventListener("touchmove", onTouchMove);

    return () => {
      document.removeEventListener("mousemove", onMouseMove);
      document.removeEventListener("touchmove", onTouchMove);
    };
  });

  return <pre>{JSON.stringify(state, null, 2)}</pre>;
};
Result

API

useRafState

Returns

readonly [S, React.Dispatch<React.SetStateAction<S>>]: 包含以下元素的元组:

  • state 的当前值。
  • requestAnimationFrame 中更新 state 值的函数。

Arguments

参数名描述类型默认值
initialState状态值S | (() => S) (必填)-