React hooks - useRef

useRef

用法

useRef 函数返回一个可变的 ref 对象,该对象只有一个 current 属性。可以在调用 useRef 函数时为其指定初始值。并且这个返回的 ref 对象在组件的整个生命周期内保持不变。

javascript 复制代码
// 1. 导入 useRef
import { useRef } from 'react'
// 2. 调用 useRef 创建 ref 对象
const refObj = useRef(初始值)
// 3. 通过 ref.current 访问 ref 中存储的值
console.log(refObj.current)
特点
  1. 获取 DOM 元素或子组件的实例对象
javascript 复制代码
import React, { useRef } from 'react'

export const InputFocus: React.FC = () => {
  // 1. 创建 ref 引用
  const iptRef = useRef<HTMLInputElement>(null) // 加上泛型引用后就可以提示代码了

  const getFocus = () => {
    // 3. 调用 focus API,让文本框获取焦点
    iptRef.current?.focus() // iptRef.current可能为空,后面使用链式调用?.来保证不报错
  }

  return (
    <>
      {/* 2. 绑定 ref 引用 */}
      <input type="text" ref={iptRef} />
      <button onClick={getFocus}>点击获取焦点</button>
    </>
  )
}
  1. 存储渲染周期之间共享的数据
javascript 复制代码
export const Counter: React.FC = () => {
  const [count, setCount] = useState(0)
  const prevCountRef = useRef<number>() // 默认值为 undefined,泛型为number,将来要存number类型的值
  let preCount // 创建一个变量存储旧值无法实现,因为每次count发生变化时组件重新渲染导致preCount初始化为undefined
  const add = () => {
    setCount((c) => c + 1)
    prevCountRef.current = count // 记录旧值到prevCountRef中
    // preCount = count // 错误写法,无法实现
  }
  return (
    <>
      <h1>新值是:{count},旧值是:{prevCountRef.current} </h1>
      <button onClick={add}>+1</button>
    </>
  )
}
注意事项
  1. 组件rerender(重新渲染)时useRef不会被重复初始化
  2. ref.current发生变化时不会造成组件的rerender(重新渲染)
  3. ref.current不能作为其他hooks(useMemo、useCallback、useEffect 等) 的依赖项
    组件首次渲染后会触发一次 useEffect 。但当time.current 变化不会触发 useEffect 的重新执行。
javascript 复制代码
export const RefTimer: React.FC = () => {
  const time = useRef(Date.now())
  const updateTime = () => {
    time.current = Date.now()
  }
  useEffect(() => {
    console.log('time 的值发生了变化:' + time.current)
  }, [time.current])

  return (
    <>
      <h3>时间戳是:{time.current}</h3>
      <button onClick={updateTime}>给ref赋新值</button>
    </>
  )
}
相关推荐
用户938515635074 小时前
React 受控/非受控组件与 React.memo 性能优化——从本质到实战
前端·javascript·react.js
半个落月5 小时前
从零梳理 React Router:路由、懒加载、嵌套页面与登录鉴权
前端·react.js
光影少年6 小时前
Codex 斜杠指令体系与业务场景调度实战
前端·react.js·reactivex
Darling噜啦啦8 小时前
别再逐层传 Props 了!useContext + 自定义 Hook 彻底搞定 React 跨层通信
react.js
先吃饱再说8 小时前
层层传递太“痛”了:useContext 给 React 组件装了个“无线遥控器”
前端·react.js·前端框架
To_OC8 小时前
从一个颜色选择器说起:我终于整明白了 React+TS 里的 model 与 api 分层
前端·react.js·typescript
嘟嘟071712 小时前
学了 useContext 还是不理解?从 prop drilling 到 useMouse 的一次完整复盘
前端·javascript·react.js
触底反弹12 小时前
JS 运行原理与 Event Loop:从 Web Worker 实战说起
前端·javascript·react.js
喜欢睡觉13 小时前
跨越组件层级的"任意门":React Context 与自定义 Hooks 完全入门指南
react.js
moMo13 小时前
前端路由,其实就是三个对象在演戏
前端·react.js