首页 > 解决方案 > 每次组件在 React.js 中呈现时,useCallback 钩子都会创建一个函数吗?

问题描述

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

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

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

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

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

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

关于useCallbackuseMemo我有什么遗漏吗?

标签: reactjsreact-hooks

解决方案


在这里,我做了一个例子,你可以看到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);
<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>


推荐阅读