- ReactJS 教程
- ReactJS 教程
- ReactJS - 简介
- ReactJS - 安装
- ReactJS - 特性
- ReactJS - 优点和缺点
- ReactJS - 架构
- ReactJS - 创建 React 应用程序
- ReactJS - JSX
- ReactJS - 组件
- ReactJS - 嵌套组件
- ReactJS - 使用组件
- ReactJS - 组件集合
- ReactJS - 样式
- ReactJS - 属性(props)
- ReactJS - 使用属性创建组件
- ReactJS - props 验证
- ReactJS - 构造函数
- ReactJS - 组件生命周期
- ReactJS - 事件管理
- ReactJS - 创建事件感知组件
- ReactJS - 在Expense Manager APP中引入事件
- ReactJS - 状态管理
- ReactJS - 状态管理 API
- ReactJS - 无状态组件
- ReactJS - 使用 React Hooks 进行状态管理
- ReactJS - 使用 React 钩子的组件生命周期
- ReactJS - 组件的布局
- ReactJS - 分页
- ReactJS - Material 用户界面
- ReactJS - Http 客户端编程
- ReactJS - 表单编程
- ReactJS - 受控组件
- ReactJS - 不受控制的组件
- ReactJS - Formik
- ReactJS - 条件渲染
- ReactJS - 列表
- ReactJS - 键
- ReactJS - 路由
- ReactJS - 冗余
- ReactJS - 动画
- ReactJS - 引导程序
- ReactJS - 地图
- ReactJS - 表格
- ReactJS - 使用 Flux 管理状态
- ReactJS - 测试
- ReactJS - CLI 命令
- ReactJS - 构建和部署
- ReactJS - 示例
- ReactJS - 钩子简介
- ReactJS - 使用 useState
- ReactJS - 使用 useEffect
- ReactJS - 使用 useContext
- ReactJS - 使用 useRef
- ReactJS - 使用 useReducer
- ReactJS - 使用 useCallback
- ReactJS - 使用 useMemo
- ReactJS - 自定义钩子
- ReactJS - 可访问性
- ReactJS - 代码拆分
- ReactJS - 上下文
- ReactJS - 错误边界
- ReactJS - 转发引用
- ReactJS - 片段
- ReactJS - 高阶组件
- ReactJS - 与其他库集成
- ReactJS - 优化性能
- ReactJS - 分析器 API
- ReactJS - 门户
- ReactJS - 没有 ES6 ECMAScript 的 React
- ReactJS - 没有 JSX 的 React
- ReactJS - 协调
- ReactJS - 引用和 DOM
- ReactJS - 渲染属性
- ReactJS - 静态类型检查
- ReactJS - 严格模式
- ReactJS - Web 组件
- ReactJS - 日期选择器
- ReactJS - Helmet
- ReactJS - 内联样式
- ReactJS - 属性类型
- ReactJS - 浏览器路由器
- ReactJS - DOM
- ReactJS - 旋转木马
- ReactJS - 图标
- ReactJS - 表单组件
- ReactJS - 参考 API
ReactJS - 使用 useCallback
useCallback 钩子类似于 useMemo 钩子,并提供记忆函数而不是值的功能。由于回调函数在JavaScript编程中是不可或缺的一部分,而回调函数是通过引用传递的,因此react提供了一个单独的钩子,useCallback来记忆回调函数。从理论上讲,useCallback 功能可以使用 useMemo 钩子本身来实现。但是,useCallback 提高了 react 代码的可读性。
useCallback 钩子的签名
useCallback 钩子的签名如下 -
const <memoized_callback_fn> = useCallback(<callback_fn>, <dependency_array>);
在这里,useCallback 接受两个输入并返回一个记忆化的回调函数。输入参数如下:
- callback_fn - 要记住的回调函数。
- dependency_array - 保留回调函数所依赖的变量。
useCallback 钩子的输出是 callback_fn 的记忆回调函数。useCallback 钩子的用法如下 -
const memoizedCallbackFn = useCallback(() => {
// code
}, [a, b])
应用 useCallback
让我们通过创建一个 react 应用程序来学习如何应用 useCallback 钩子。
首先,使用 create-react-app 命令创建并启动一个 react 应用程序,如下所示:
cd myapp
npm start
接下来,在组件文件夹 (src/components/PureListComponent.js) 下创建一个组件 PureListComponent
import React from "react";
function PureListComponent() {
return <div>List</div>
}
export default PureListComponent
接下来,使用PureListComponent组件更新根组件,如下所示 -
import PureListComponent from './components/PureListComponent';
function App() {
return (
<div style={{ padding: "5px" }}>
<PureListComponent />
</div>
);
}
export default App;
接下来,打开 PureListComponent.js 并添加两个道具
- 要在组件中显示的项目列表
- callback 函数,用于显示用户在控制台中单击的项目
import React from "react";
function PureListComponent(props) {
const items = props['items'];
const handleClick = props['handleClick']
console.log("I am inside the PureListComponent")
return (
<div>
{items.map((item, idx) =>
<span key={idx} onClick={handleClick}>{item} </span>
)}
</div>
)
}
export default React.memo(PureListComponent)
在这里,我们有,
- 使用 items 属性来获取项目列表
- 使用 handleClick 获取 click 事件的处理程序
- 使用 React.memo 包装组件以记住组件。由于该组件将为给定的输入集呈现相同的输出,因此在 react 中称为 PureComponent。
接下来,让我们更新App.js并使用 PureListComponent,如下所示 -
import React, {useState, useEffect} from 'react';
import PureListComponent from './components/PureListComponent';
function App() {
// array of numbers
var listOfNumbers = [...Array(100).keys()];
// callback function
const handleCallbackFn = (e) => { console.log(e.target.innerText) }
const [currentTime, setCurrentTime] = useState(new Date())
useEffect(() => {
let interval = setInterval(() => {
setCurrentTime(new Date())
}, 1000)
return () => clearInterval(interval)
}, [currentTime])
return (
<div style={ { padding: "5px" } }>
<PureListComponent items={listOfNumbers} handleClick={handleCallbackFn}/>
<div>Time: <b>{currentTime.toLocaleString().split(',')[1]}</b></div>
</div>
);
}
export default App;
在这里,我们包含了一个状态 currentTime,并使用 setInterval 每秒更新一次,以确保组件每秒重新渲染一次。
我们可能认为 PureListComponent 不会每秒重新渲染一次,因为它使用 React.memo。但是,它将重新呈现,因为 props 值是引用类型。
接下来,更新根组件并使用 useMemo 和 useCallback 来保留数组和回调函数,如下所示 -
import React, {useState, useEffect, useCallback, useMemo} from 'react';
import PureListComponent from './components/PureListComponent';
function App() {
// array of numbers
const listOfNumbers = useMemo(() => [...Array(100).keys()], []);
// callback function
const handleCallbackFn = useCallback((e) => console.log(e.target.innerText), [])
const [currentTime, setCurrentTime] = useState(new Date())
useEffect(() => {
let interval = setInterval(() => {
setCurrentTime(new Date())
}, 1000)
return () => clearInterval(interval)
}, [currentTime])
return (
<div style={ { padding: "5px" } }>
<PureListComponent items={listOfNumbers} handleClick={handleCallbackFn}/>
<div>Time: <b>{currentTime.toLocaleString().split(',')[1]}</b></div>
</div>
);
}
export default App;
在这里,我们有,
- 使用 useMemo 保留 items 数组
- 使用 useCallback 保留 handleClick 回调函数
最后,在浏览器中检查应用程序,它不会每秒重新渲染 PureListComponent。
useCallback 的用例
useCallback 钩子的一些用例如下 -
- 具有功能属性的纯功能组件
- useEffect 或其他具有依赖项功能的钩子
- 在去抖动/节流或类似操作期间使用功能
优点
useCallback hook 的优点如下 -
- 简单易用的 API
- 通俗易懂
- 提高应用程序的性能
缺点
从技术上讲,useCallback 没有缺点。但是,在应用程序中大量使用 useCallback 会带来以下缺点。
- 降低应用程序的可读性
- 降低应用程序的可理解性
- 调试应用程序很复杂
- 开发人员应该对 JavaScript 语言有深入的理解才能使用它
总结
useCallback 易于使用并提高了性能。同时,只有在绝对必要时才应使用 useCallback。它不应在所有情况下都使用。一般规则是检查应用程序的性能。如果需要改进,那么我们可以检查 useCallback 的使用是否有助于提高性能。如果我们得到积极的回应,那么我们就可以使用它。否则,我们可以将其留给反应来改进和优化应用程序的性能。