在 ReactJS 中结合 useState 和 useRef

Combining useState and useRef in ReactJS

我有一些变量需要参考和状态。我在这里找到了一些对我有帮助的东西:

几乎只是保持两个变量同步(在伪代码中):

const [track, setTrack] = useState('INIT');
const trackRef = useRef('INIT');

// Whenever changing, just both are updated
setTrack('newValue');
trackRef.current = 'newValue';

我想知道将这两个组合成一个新的钩子是否有益。像这样:

const useStateRef(initialState: any) {
  const [state, setState] = useState<typeof initialState>(initialState);
  const ref = useRef<typeof initialState>(initialState);

  useEffect(() => {
    setState(ref);
  }, [ref]);

  return [state, ref];
}

最好的方法是什么?做这样的事情甚至很重要吗?

(背景是,我有一些自重复的函数,需要引用来改变它们正在做的事情。但是我还需要状态变量来在相同的变量发生变化时重新呈现可见的变化......也许有一种完全不同的方法可以做到这一点,但我仍然对这种方法感到好奇。)

这是可能的,但为了使类型正确,您应该使用 generics 而不是 any,并且需要反转效果挂钩 - 更改 ref.currentstate 改变时。您还需要 return 状态 setter 以更改 useStateRef.

的消费者中的值
const useStateRef = <T extends unknown>(initialState: T) => {
  const [state, setState] = useState(initialState);
  const ref = useRef(initialState);

  useEffect(() => {
    ref.current = state;
  }, [state]);

  return [state, setState, ref];
};

或者,要同步更新,去除效果挂钩:

if (ref.current !== state) ref.current = state;

另请注意,永远不需要只包含 原始 的引用。 const trackRef = useRef('INIT'); 可以完全重构并替换为 track。在处理 对象 时,引用通常很有用,例如 HTMLElements。