1

想象一下这种情况。

接收对象并基于对象属性的钩子进行一些计算并返回结果。

export const useTestHook = (someOject) => {
  const [updated, set] = useState({ val1: null, val2: null });

  useEffect(() => {
    set({
      val1: `${someOject.val1}_-`,
      val2: `${someOject.val2}_-`,
    })
  }, [someOject]);

  return updated;
}

使用钩子的组件将这些值分开,因此需要初始化一个新对象,以便将其传递给钩子。然后通过一些回调将钩子的结果传递回父级。

function TestComp({ onChange, parentValue }) {
  const [value1, setValue1] = useState('value1');
  const [value2, setValue2] = useState('value2');

  // since mergedValues is used as dependency of the hook I need to 'memoize' it otherwise it gets 
  // recreated on each re-render and will cycle 
  const mergedValues = useMemo(() => ({
    val1: value1,
    val2: value2
  }), [value1, value2]);

  const updatedVals = useTestHook(mergedValues);

  useEffect(() => {
    onChange(updatedVals);
  }, [onChange, updatedVals]);

  return (
    <div>
      Hello
    </div>
  );
}

父级可以对该值进行一些其他计算,并将结果返回给子级。

function App() {
  const [value, set] = useState('value1');

  return (
    <TestComp onChange={set} parentValue={value} />
  );
}

当对象用作某些效果的依赖项时,在反应组件中处理对象创建的正确方法是什么?可以用useMemo钩子吗?

const mergedValues = useMemo(() => ({
    val1: value1,
    val2: value2
  }), [value1, value2]);

官方文档说“你可能依赖 useMemo 作为性能优化,而不是语义保证。” https://reactjs.org/docs/hooks-reference.html#usememo

另一种方法是将钩子的道具从一个对象更改为简单的值,并从钩子的 useEffect 中的这些值创建对象,但这种方法不适合我。

4

1 回答 1

0

当对象用作某些效果的依赖项时,在反应组件中处理对象创建的正确方法是什么?可以使用 useMemo 钩子吗?

是的,您可以使用useMemo,但有一个警告。由于文档是这样说的:

您可能依赖 useMemo 作为性能优化,而不是语义保证。将来,React 可能会选择“忘记”一些以前记忆的值,并在下一次渲染时重新计算它们

这意味着在某些情况下useMemo可以忘记它的存储值并仍然给你一个新对象,useEffect如果它使用该对象作为依赖项,它可能会触发,这可能不是你想要的。但是,如果您useEffect的过度燃烧不是问题,那么这不是问题。

您也可以这样做,并且不需要useMemo(假设val1并且val2是原语):

  useEffect(() => {
    set({
      val1: `${someOject.val1}_-`,
      val2: `${someOject.val2}_-`,
    })
  }, [someOject.val1, someOject.val2]);
于 2022-01-21T11:58:41.293 回答