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>
  )
}


相关文章
|
1月前
|
前端开发 JavaScript
【边做边学】React Hooks (二)——useEffect Hook
【边做边学】React Hooks (二)——useEffect Hook
|
1月前
|
前端开发 JavaScript
React中useEffect Hook使用纠错
React中useEffect Hook使用纠错
23 0
|
1月前
|
前端开发 JavaScript 测试技术
React Hooks之useState、useRef
React Hooks之useState、useRef
|
1月前
|
存储 前端开发 JavaScript
React Hooks的useState、useRef使用
React Hooks的useState、useRef使用
37 2
|
1月前
|
前端开发 中间件 数据安全/隐私保护
React路由进阶方法
React路由进阶方法
36 1
|
1月前
|
存储 前端开发 JavaScript
[React] useRef用法和特性
[React] useRef用法和特性
|
1月前
|
前端开发 JavaScript
React useRef 详细使用
React useRef 详细使用
41 0
|
1月前
|
自然语言处理 前端开发 JavaScript
说说你对 React Hook的闭包陷阱的理解,有哪些解决方案?
说说你对 React Hook的闭包陷阱的理解,有哪些解决方案?
65 0
|
6月前
|
自然语言处理 前端开发 JavaScript
美丽的公主和它的27个React 自定义 Hook(四)
美丽的公主和它的27个React 自定义 Hook(四)
|
6月前
|
存储 前端开发 数据可视化
美丽的公主和它的27个React 自定义 Hook(三)
美丽的公主和它的27个React 自定义 Hook(三)