react 进阶hook 之 useRef hook

简介: 在react 的类组件中,我们可以在类中定义属性 ref 详情, 但是在函数组件是不能直接使用 ref, 如果需要使用 ref 那么就只能是 ref 转发, 说实话这个函数组件的 ref 转发 是有点绕, 而且还会增加组件的层级。个人感觉不怎么友好。
  • 看到 ref 大家不管是在vue 中 还是在react 中都比较熟悉, vue3 的ref 有两个,vue2 有一个,但是ref 的作用都有一个公共的作用,那就是获取真实的dom。


  • 在react 的类组件中,我们可以在类中定义属性 ref 详情, 但是在函数组件是不能直接使用 ref, 如果需要使用 ref 那么就只能是 ref 转发, 说实话这个函数组件的 ref 转发 是有点绕, 而且还会增加组件的层级。个人感觉不怎么友好。


语法


const refContainer = useRef(initialValue);


参数 initialValue: 初始值,可以传,也可以不传,如果参数传了那就是用来固定数据的引用,这个有点类似 vue3中的ref, 只是在这里的对象是{current: xxx} 而vue3 中的是 {value: xxxx}


  • 返回值: 是一个{current:xxx}对象,里面绑定给 react 的内置组件,那current 是一个dom, 不绑定且有参数的话,那么就是一个 固定引用的数据


案例


绑定react 内置组件 获取dom


import React, { useCallback, useRef } from 'react'
export default function TestRefHook() {
  // ref 对象
  const inputRef = useRef<HTMLInputElement>(null)
  // 使用 callback 绑定函数引用,养成习惯
  const handle= useCallback((e: React.ChangeEvent<HTMLInputElement> ) =>{
    console.log(inputRef.current,'----====');
  },[])
  return (
    <div>
      <input type="text" ref={inputRef} onChange={handle}/>
    </div>
  )
}


效果


20210409111603816.png


ref 作用于react 内置组件,获取dom


ref 作用于组件


ref 只能直接作用于类组件,获取的是类的实例,不能直接作用于函数组件,函数组件没有实例,如果想获取函数组件里面的dom 或者是类组件的dom, 还是需要使用 ref 转发来获取


直接作用于类组件


import React, { PureComponent, useCallback, useRef } from 'react'
class TestComp extends PureComponent {
  render() {
    return (
      <>
        <h1>我是测试组件</h1>
      </>
    )
  }
}
export default function TestRefHook() {
  // ref 对象
  const inputRef = useRef<TestComp>(null)
  // 使用 callback 绑定函数引用,养成习惯
  const handle = useCallback((e: React.MouseEvent<HTMLButtonElement>) => {
    console.log(inputRef.current, '----====');
  }, [])
  return (
    <div>
      <TestComp ref={inputRef} />
      <button onClick={handle}>获取类组件的实例</button>
    </div>
  )
}


效果


2021040911261534.png


ref hooks 用于固定数据的引用


请使用hooks 来实现一个定时器,我们可能会写以下代码实现。


效果


20210409121944780.gif


setTimeout 实现


import React, { useEffect, useState } from 'react'
export default function TestRefHook() {
  // 计时器的数据
  const [n, setN] = useState(10)
  // 使用副作用
  useEffect(() => {
    if (n === 0) return;
    // 这里为啥要使用setTimeout,因为effect hooks 在初始化的时候会调用函数,
    // 启动一个定时器,并且在先清理上一次的副作用
    const timer = setTimeout(() => {
      setN(n - 1)
    }, 1000)
    return () => {
      clearTimeout(timer)
    }
  }, [n])
  return (
    <div>
      <span>计时器</span>
      <span>{n}</span>
    </div>
  )
}


使用 setInterval 来实现


需要每一次都清理掉副作用,不然会多个定时器,出现问题


import React, { useEffect, useState } from 'react'
export default function TestRefHook() {
  // 计时器的数据
  const [n, setN] = useState(10)
  // 使用副作用
  useEffect(() => {
    if (n === 0) return;
    const timer = setInterval(() => {
      setN(n - 1)
    }, 1000)
    return () => {
      clearInterval(timer)
    }
  }, [n])
  return (
    <div>
      <span>计时器</span>
      <span>{n}</span>
    </div>
  )
}


使用ref hooks 来实现


import React, { useEffect, useRef, useState } from 'react'
export default function TestRefHook() {
  // 计时器的数据
  const [n, setN] = useState(10)
  // 使用ref来固定数据
  const nRef = useRef(n)
  // 使用副作用
  useEffect(() => {
    const timer = setInterval(() => {
      nRef.current--
      setN(nRef.current)
      if (nRef.current === 0) {
        clearInterval(timer)
      };
    }, 1000)
  }, []) // 这里不能写任何的依赖,不然会没用
  return (
    <div>
      <span>计时器</span>
      <span>{n}</span>
    </div>
  )
}


相关文章
|
4月前
|
前端开发 JavaScript
React中函数式Hooks之useRef的使用
React中函数式Hooks的useRef用于获取DOM元素的引用,示例代码演示了其基本用法。
41 3
|
5月前
|
前端开发
React使用useRef ts 报错
【8月更文挑战第17天】
93 4
|
3月前
|
存储 缓存 JavaScript
深入理解 React-Hooks 之 useRef
【10月更文挑战第20天】总之,`useRef` 是 React-Hooks 中一个非常实用的工具,它为我们提供了一种灵活而强大的方式来处理组件中的各种数据和操作。通过深入理解和掌握 `useRef` 的原理和用法,我们能够更好地构建高效、稳定的 React 应用。
49 6
|
3月前
|
存储 前端开发 JavaScript
React useState 和 useRef 的区别
本文介绍了 React 中 `useState` 和 `useRef` 这两个重要 Hook 的区别和使用场景。`useState` 用于管理状态并在状态变化时重新渲染组件,适用于表单输入、显示/隐藏组件、动态样式等场景。`useRef` 则用于在渲染之间保持可变值而不触发重新渲染,适用于访问 DOM 元素、存储定时器 ID 等场景。文章还提供了具体的代码示例,帮助读者更好地理解和应用这两个 Hook。
69 0
|
4月前
|
存储 前端开发 JavaScript
react的useRef用什么作用
react的useRef用什么作用
76 1
|
5月前
|
前端开发
React 中的 Hook 概念
【8月更文挑战第31天】
46 0
|
6月前
|
前端开发
React useImperativeHandle Hook
【7月更文挑战第1天】React useImperativeHandle Hook
36 3
|
6月前
|
前端开发 JavaScript 数据格式
react18【系列实用教程】Hooks (useState,useReducer,useRef,useEffect,useContext,useMemo,useCallback,自定义 Hook )
react18【系列实用教程】Hooks (useState,useReducer,useRef,useEffect,useContext,useMemo,useCallback,自定义 Hook )
125 1
|
6月前
|
存储 前端开发 JavaScript
react hooks 学习进阶
【7月更文挑战第12天】 React Hooks(自16.8版起)让函数组件能处理状态和副作用。useState用于添加状态管理,useEffect处理副作用,useContext共享数据,useReducer处理复杂状态逻辑,useRef获取引用。进阶技巧涉及性能优化,如useMemo和useCallback,以及遵循规则避免在不适当位置调用Hooks。理解异步更新机制和结合Redux等库提升应用复杂性管理。持续学习新技巧是关键。
68 0
|
6月前
|
前端开发
Vue3 【仿 react 的 hook】封装 useTitle
Vue3 【仿 react 的 hook】封装 useTitle
66 0