logoahooks dive
State

useRafState

用于管理 RAF 状态的 Hook

用法

requestAnimationFrame 中更新状态。

滚动页面,观察两个组件更新次数的差异
[WithUseState] update state count: 0 / 1
[WithUseRafState] update state count: 0 / 1

[WithUseState] update state count: 0 / 10
[WithUseRafState] update state count: 0 / 10

源码

import { useCallback, useRef, useState } from 'react';
import type { Dispatch, SetStateAction } from 'react';
import useUnmount from '../useUnmount';

function useRafState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];
function useRafState<S = undefined>(): [S | undefined, Dispatch<SetStateAction<S | undefined>>];

function useRafState<S>(initialState?: S | (() => S)) {
  const ref = useRef(0);
  const [state, setState] = useState(initialState);

  const setRafState = useCallback((value: S | ((prevState: S) => S)) => {
    cancelAnimationFrame(ref.current);

    ref.current = requestAnimationFrame(() => {
      setState(value);
    });
  }, []);

  useUnmount(() => {
    cancelAnimationFrame(ref.current);
  });

  return [state, setRafState] as const;
}

export default useRafState;

解读

TODO

Last updated on

On this page