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 事件 ReactJS - 状态管理 ReactJS - 状态管理 API ReactJS - 无状态组件 ReactJS - Hooks 进行状态管理 ReactJS - Hooks 的组件生命周期 ReactJS - 布局组件 ReactJS - 分页 ReactJS - Material UI ReactJS - Http 客户端编程 ReactJS - 表单编程 ReactJS - 受控组件 ReactJS - 非受控组件 ReactJS - Formik ReactJS - 条件渲染 ReactJS - 列表 ReactJS - Key 键 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 - 上下文 ReactJS - 错误边界 ReactJS - 转发 Refs ReactJS - 片段 ReactJS - 高阶组件 ReactJS - 与其他库集成 ReactJS - 优化性能 ReactJS - Profiler API ReactJS - Portals ReactJS - 不使用 ES6 ECMAScript ReactJS - 不使用 JSX 的 React ReactJS - Reconciliation ReactJS - Refs 和 DOM ReactJS - 渲染道具 ReactJS - 静态类型检查 ReactJS - 严格模式 ReactJS - Web 组件

其他概念

ReactJS - 日期选择器 ReactJS - Helmet ReactJS - 内联样式 ReactJS - PropTypes ReactJS - BrowserRouter ReactJS - DOM ReactJS - 轮播 ReactJS - 图标 ReactJS - 表单组件 ReactJS - 参考 API

ReactJS 有用资源

ReactJS - 快速指南 ReactJS - 备忘录 Axios - 备忘录 ReactJS - 有用资源 ReactJS - 讨论


ReactJS - useRef

React 会在组件状态发生变化时自动发出 HTML 元素。这大大简化了 UI 开发,因为只需更新组件的状态即可。传统上,直接访问 DOM 元素来更新组件的 UI 是很正常的。

有时我们可能需要回退到直接访问 DOM 元素并更新组件的 UI。React ref 在此场景中提供帮助。它提供对 DOM 元素的直接访问。此外,它确保组件能够与 React Virtual DOM 和 HTML DOM 顺利配合使用。

React 提供了一个函数 createRef 来在基于类的组件中创建 ref。函数组件中 createRef 的对应项是 useRef Hooks(钩子)。让我们在本章中学习如何使用 useRef。

useRef Hooks(钩子)的签名

useRef 的目的是返回一个可变对象,该对象将在重新渲染之间持续存在。 useRef 的签名如下 −

<refObj> = useRef(<val>)

此处,

  • val 是要为返回的可变对象 refObj 设置的初始值。

  • refObj 是Hooks(钩子)返回的对象。

要自动将 DOM 对象附加到 refObj,应在元素的 ref props 中设置它,如下所示 −

<input ref={refObj} />

要访问附加的 DOM 元素,请使用 refObj 的 current 属性,如下所示 −

const refElement = refObj.current

应用 ref hook

让我们在本章中通过创建一个 React 应用程序来学习如何应用 useRef

首先,创建一个新的 React 应用程序并使用以下命令启动它。

create-react-app myapp
cd myapp
npm start

接下来,在组件文件夹 (src/components/RefInput.js) 下创建一个 React 组件 RefInput

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 Hooks(钩子)来处理计数器状态变量(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 props 将其附加到相关元素。

  • 创建了另一个 ref,labelRef 来表示问候消息元素,并通过 ref props 将其附加到相关元素。

  • 将事件处理程序 handleChange 附加到输入元素。事件处理程序使用 inputRef ref 获取问候消息,并使用 labelRef ref 更新消息。

接下来,在浏览器中打开应用程序并输入您的姓名。应用程序将更新问候消息,如下所示。

Applying Ref Hook

检查您的控制台,您会注意到组件未重新渲染。由于 react 仅在状态更改时重新渲染,而 ref 不会进行任何状态更改,因此组件不会重新渲染。

接下来,单击 + 按钮。当状态(计数)发生变化时,它将通过重新渲染组件来更新计数器。如果仔细观察,您会发现消息保持不变。这种行为的原因是 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。