每次组件在 React.js 中呈现时,useCallback 钩子都会创建一个函数吗?

Goo*_*mja 6 reactjs react-hooks

在求职面试中,有人问我如何在 React 中优化组件。

所以我用一个使用useCallbackuseMemo钩子的例子来回答。

因为每当组件重新渲染时,组件内部声明的函数和变量都是新创建的,这会导致这些新创建的值占用内存空间。

然而,在这两个钩子的帮助下,可以节省内存,因为使用useCallbackuseMemo可以防止通过保存和重用先前的结果来一次又一次地创建函数和变量,只要依赖数组中的状态没有改变在组件重新渲染期间。

到目前为止,这是我的答案。但是面试官说useCallback不阻止创建函数。即使使用了useCallback,仍然会创建一个函数。

我不明白这部分。在 useCallback 钩子中如何再次创建该函数?

我对useCallbackuseMemo有什么遗漏吗?

Rya*_* Le 3

我在这里做了一个例子,以便您可以看到useCallback实际效果:

在下面的示例中:useCallback将阻止changeWithUseCallback重新创建每个新渲染,结果Child1永远不会重新渲染,因为它的道具(changeWithUseCallback)从未重新创建。

否则,在Child2组件中,它的 prop (changeWithoutUseCallback) 总是在渲染期间重新创建,因此组件本身将重新渲染。

请注意,如果组件的 props 没有改变,React.memo将跳过渲染组件

所以我想说你是对的useCallback,它将在渲染期间或渲染期间保留函数/变量引用prevent creating new function/variable

function App() {
  const [value, setValue] = React.useState(0);
  const changeWithUseCallback = React.useCallback(() => {
    console.log("onChangeChild");
  }, []);
  const changeWithoutUseCallback = () => {
    console.log("onChangeChild");
  };
  return (
    <div className="App">
      <button type="button" onClick={() => setValue(value + 1)}>
        Change value
      </button>
      <h1>{value}</h1>
      <Child1 onChange={changeWithUseCallback} />
      <Child2 onChange={changeWithoutUseCallback} />
    </div>
  );
}

const Child1 = React.memo(({ onChange }) => {
  console.log("Child1 render!!!");
  return null;
});

const Child2 = React.memo(({ onChange }) => {
  console.log("Child2 render!!!");
  return null;
});

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Run Code Online (Sandbox Code Playgroud)

  • 据我了解,函数/变量仍然被重新创建。毕竟,整个组件都会被重新渲染/重新执行 -&gt; 每次都会声明和设置变量。唯一的区别是它们最终引用内存中的相同位置。 (4认同)