- ReactJS 教程
- 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 Hooks 进行组件生命周期管理
- ReactJS - 布局组件
- ReactJS - 分页
- ReactJS - Material UI
- ReactJS - Http 客户端编程
- ReactJS - 表单编程
- ReactJS - 受控组件
- ReactJS - 非受控组件
- ReactJS - Formik
- ReactJS - 条件渲染
- ReactJS - 列表
- ReactJS - Keys
- ReactJS - 路由
- ReactJS - Redux
- ReactJS - 动画
- ReactJS - Bootstrap
- ReactJS - Map
- ReactJS - 表格
- ReactJS - 使用 Flux 管理状态
- ReactJS - 测试
- ReactJS - CLI 命令
- ReactJS - 构建和部署
- ReactJS - 示例
- Hooks
- ReactJS - Hooks 简介
- ReactJS - 使用 useState
- ReactJS - 使用 useEffect
- ReactJS - 使用 useContext
- ReactJS - 使用 useRef
- ReactJS - 使用 useReducer
- ReactJS - 使用 useCallback
- ReactJS - 使用 useMemo
- ReactJS - 自定义 Hooks
- ReactJS 高级
- ReactJS - 可访问性
- ReactJS - 代码分割
- ReactJS - Context
- ReactJS - 错误边界
- ReactJS - 转发 Refs
- ReactJS - Fragments
- ReactJS - 高阶组件
- ReactJS - 集成其他库
- ReactJS - 性能优化
- ReactJS - Profiler API
- ReactJS - Portals
- ReactJS - 无 ES6 ECMAScript 的 React
- ReactJS - 无 JSX 的 React
- ReactJS - 调和
- ReactJS - Refs 和 DOM
- ReactJS - Render Props
- ReactJS - 静态类型检查
- ReactJS - Strict Mode
- ReactJS - Web Components
- 其他概念
- ReactJS - 日期选择器
- ReactJS - Helmet
- ReactJS - 内联样式
- ReactJS - PropTypes
- ReactJS - BrowserRouter
- ReactJS - DOM
- ReactJS - 轮播图
- ReactJS - 图标
- ReactJS - 表单组件
- ReactJS - 参考 API
- ReactJS 有用资源
- ReactJS - 快速指南
- ReactJS - 有用资源
- ReactJS - 讨论
ReactJS - useRef
React 会随着组件状态的变化自动发出 HTML 元素。这极大地简化了 UI 开发,因为只需更新组件的状态即可。传统上,通常需要直接访问 DOM 元素来更新组件的 UI。
有时我们可能需要回退到直接访问 DOM 元素并更新组件的 UI。React ref 在这种情况下提供了帮助。它提供了对 DOM 元素的直接访问。此外,它确保组件与 React 虚拟 DOM 和 HTML DOM 顺利协同工作。
React 提供了一个函数 createRef 用于在基于类的组件中创建 ref。函数组件中 createRef 的对应项是 useRef hook。让我们学习如何在本章中使用 useRef。
useRef hook 的签名
useRef 的目的是返回一个可变对象,该对象将在重新渲染之间持续存在。useRef 的签名如下:
<refObj> = useRef(<val>)
这里:
val 是要为返回的可变对象 refObj 设置的初始值。
refObj 是 hook 返回的对象。
为了将 DOM 对象自动附加到 refObj,应将其设置在元素的 ref 属性中,如下所示:
<input ref={refObj} />
要访问附加的 DOM 元素,请使用 refObj 的 current 属性,如下所示:
const refElement = refObj.current
应用 ref hook
让我们学习如何在本章中通过创建一个 React 应用来应用 useRef。
首先,使用以下命令创建一个新的 React 应用并启动它。
create-react-app myapp cd myapp npm start
接下来,在 component 文件夹下创建一个 React 组件 RefInput (src/components/RefInput.js)
function RefInput() { return <div>Hello World</div> } export default RefInput
接下来,更新根组件 (App.js) 以使用我们的新组件。
import RefInput from "./components/RefInput"; function App() { return ( <div style={{ padding: "5px"}}> <RefInput /> </div> ); } export default App;
接下来,向 RefInput 组件添加计数器功能,如下所示:
import {useState} from 'react' function RefInput() { const [count, setCount] = useState(0) const handleClick = () => setCount(count + 1) return ( <div> <div>Counter: {count} <button onClick={handleClick}>+</button></div> </div> ) } export default RefInput
这里我们:
使用 useState hook 来处理计数器状态变量 (count)。
在 JSX 中渲染计数器状态变量。
添加一个按钮并附加一个点击处理程序事件 (handleClick),它将使用 setCount 方法递增计数器。
接下来,添加一个输入字段并根据用户在输入字段中输入的值显示问候消息,如下所示:
import {useState, useRef} from 'react' function RefInput() { const [count, setCount] = useState(0) const inputRef = useRef(null) const labelRef = useRef(null) console.log("RefInput is (re)rendered") const handleClick = () => setCount(count + 1) const handleChange = () => labelRef.current.innerText = inputRef.current. value == "" ? "World" : inputRef.current.value return ( <div> <div>Counter: {count} <button onClick={handleClick}>+</button></div> <div style={{ paddingTop: "5px"}}> <label>Enter your name: </label><input type="text" name="username" ref={inputRef} onChange={handleChange}/> <br /> <div>Hello, <span ref={labelRef}></span></div> </div> </div> ) } export default RefInput
这里我们:
创建一个 ref,inputRef 来表示输入元素,并通过 ref 属性将其附加到相关元素。
创建另一个 ref,labelRef 来表示问候消息元素,并通过 ref 属性将其附加到相关元素。
将事件处理程序 handleChange 附加到输入元素。事件处理程序使用 inputRef ref 获取问候消息,并使用 labelRef ref 更新消息。
接下来,在浏览器中打开应用程序并输入您的姓名。应用程序将更新问候消息,如下所示。
检查您的控制台,您会注意到组件没有重新渲染。由于 React 仅在状态更改时重新渲染,而 ref 不会进行任何状态更改,因此组件不会重新渲染。
接下来,单击“+”按钮。它将通过重新渲染组件来更新计数器,因为状态 (count) 已更改。如果您仔细观察,您会发现消息保持不变。这种行为的原因是 ref 值由 React 在渲染之间保留。
useRef 的用例
useRef 的一些用例如下:
访问 JavaScript DOM API - JavaScript DOM API 提供了丰富的功能来操作应用程序的 UI。当应用程序功能需要访问 JavaScript DOM API 时,可以使用 useRef 来检索原始 DOM 对象。一旦检索到原始 DOM 对象,应用程序就可以使用 DOM API 来访问所有功能。DOM API 的一些示例如下:
聚焦输入元素
选择文本
使用媒体播放 API 播放音频或视频
命令式动画 - Web 动画 API 通过命令式编程而不是声明式编程提供了一套丰富的动画功能。要使用 Web 动画 API,我们需要访问原始 DOM。
与第三方库集成 - 由于第三方库需要访问原始 DOM 来执行其功能,因此必须使用 useRef 从 React 获取 DOM 引用并将其提供给第三方库。
总结
即使 React 开发 UI 的方式简单易用,但在某些情况下,基于 DOM API 开发 UI 也有其自身的优势。useRef hook 完美地适应了这些场景,并提供了一个简单干净的 API 来直接访问 DOM 元素及其 API。