React

Ref Hooks - useRef & useImperativeHandle

在这篇文章中我们将介绍 React ref 相关知识,包括forwardRef、useRef 和 useImperativeHandle
This entry is part 5 of the seriesenjoy-react-hooks

useRef

在 React 开发中,useRef 是一个非常实用的 Hook,它允许你在不触发组件重新渲染的情况下,访问和修改 DOM 元素或保存任何可变的值。这个功能对于实现一些特定的交互效果,如聚焦输入框、测量元素大小或跟踪组件内部状态而不引起更新,尤其有用。

语法

useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内持续存在,即使在重新渲染时也保持不变。这意味着你可以使用它来存储任何需要跨渲染周期保留的数据,而不仅仅是对 DOM 的引用。

  • initialValueref 对象的 current 属性的初始值。可以是任意类型的值。这个参数在首次渲染后被忽略。
  • ref: 一个只有 current 属性的对象:
    • current: 初始值为传递的 initialValue。之后可以将其设置为其他值。如果将 ref 对象作为一个 JSX 节点的 ref 属性传递给 React,React 将为它设置 current 属性。

ref vs state

refstate 在 React 中都用于管理组件的数据,但它们的主要区别在于如何影响组件的渲染:

改变 ref 不会触发重新渲染

下面案例中分别创建了两个计数器: StateCounterRefCounter, 分别点击按钮并观察页面及控制台变化。

通过上面案例不难发现:

  1. 当点击StateCounter时,控制台打印 state count数值变化,同时UI更新。
  2. 当点击RefCounter时,控制台打印 ref count 数值变化,但UI不会更新。

以下是 stateref 的对比:

refstate
useRef(initialValue) 返回 { current: initialValue }useState(initialValue) 返回 state 变量的当前值和一个 state 设置函数 ( [value, setValue])
更改时不会触发重新渲染更改时触发重新渲染
可变 —— 你可以在渲染过程之外修改和更新 current 的值不可变 —— 你必须使用 state 设置函数来修改 state 变量,从而排队重新渲染
你不应在渲染期间读取(或写入) current 值你可以随时读取 state。但是,每次渲染都有自己不变的 state 快照。

通过ref操作DOM

使用 ref 操作 DOM 是非常常见的行为。React 内置了对它的支持。

  1. 首先声明一个初始值为nullref
  2. 然后将 ref 对象作为 ref 属性传递给想要操作的 DOM 节点的 JSX:
  3. 当 React 创建 DOM 节点并将其渲染到屏幕时,React 将会把 DOM 节点设置为 ref 对象的 current 属性。现在可以借助 ref 对象访问 <input> 的 DOM 节点,并且可以调用类似于 focus() 的方法:

useImperativeHandle

这是一个很少使用的hook, 只有当你需要 forwardRef 时, 才有可能用得到。常用于向父组件”expose“(暴露)方法。

语法

在组件顶层通过调用 useImperativeHandle 来自定义 ref 暴露出来的句柄:

用途

useImperativeHandle用于向父组件暴露暴露一个自定义的ref句柄,该句柄通常会挂载一些自定义方法。

例如: 我们定义了一个组件CustomInput, 该组件对外暴露了一个focus方法,以便调用方聚焦CustomInput。完整代码如下:

Questions? Let's chat

discord logoOPEN DISCORD
6423
members online
previous article
Context Hooks - useContext
next article
State Hooks - useReducer

A TypeScript Full Stack Blog

Share articles about Typescript, React, Next.js, Node.js and Css from time to time.
No spam, unsubscribe at any time.