在ReactJS中组合使用useState和useRef

kb5ga3dv  于 2022-12-03  发布在  React
关注(0)|答案(1)|浏览(184)

我有一些变量,我需要它们的引用和状态。我在这里找到了一些帮助我的东西:https://stackoverflow.com/a/58349377/7977410
基本上它只是保持两个变量同步(在伪代码中):

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];
}

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

cgyqldqp

cgyqldqp1#

这是可能的,但是为了使输入正确,你应该使用 generics 而不是any,并且效果钩子需要被反转-当state改变时改变ref.current。你还需要返回状态setter以改变useStateRef的消费者中的值。

const useStateRef = <T extends unknown>(initialState: T) => {
  const [state, setState] = useState(initialState);
  const ref = useRef(initialState);

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

  // Use "as const" below so the returned array is a proper tuple
  return [state, setState, ref] as const;
};

或者,若要同步更新,请移除effect挂接:

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

还要注意,永远不需要一个只包含 primitive 的ref。const trackRef = useRef('INIT');可以被完全重构掉,并替换为track。当处理 objects 时,ref通常很有用,比如HTMLElements。

相关问题