reactjs - 每次组件在 React.js 中呈现时,useCallback 钩子都会创建一个函数吗?
问题描述
在求职面试中,有人问我如何优化 React 中的组件。
所以我回答了一个使用useCallback和useMemo钩子的例子。
因为每当组件重新渲染时,组件内部声明的函数和变量都是新创建的,这会导致这些新创建的值占用内存空间。
但是,在这两个钩子的帮助下,可以节省内存,因为使用useCallback和useMemo可以防止通过保存和重用先前的结果来一次又一次地创建函数和变量,只要依赖数组中的状态没有改变在组件重新渲染期间。
到目前为止,这是我的答案。但是面试官说useCallback并不会阻止创建函数。即使使用了useCallback,仍然会创建一个函数。
我不明白这部分。这个函数是如何在 useCallback 钩子中再次创建的?
关于useCallback和useMemo我有什么遗漏吗?
解决方案
在这里,我做了一个例子,你可以看到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>
推荐阅读
- nginx - 拒绝所有不阻止返回重定向
- sql-server - 如果有人可以在服务器上进行物理访问,他们可以获得数据库的当前密码吗?
- javascript - 在前端 HTML 文件中显示 fs.readdirSync() 的输出
- java - 获取“VM初始化期间发生错误”
- firebase - 用于设置外键的 Firestore 引用数据类型
- python-3.x - 将方法移动到另一个 Python 文件
- python - Django Celery autoretry_for 和 retry_policy
- mysql - 无法创建 PoolableConnectionFactory 并打开 JDBC 连接
- java - 将双精度值显式转换为浮点数并将其存储在双精度变量中
- sql - 从表格中的逗号分隔值中获取单个值