React 第二十节 useRef 用途使用技巧注意事项详解

简述

useRef 用于操作不需要视图上渲染 的属性数据,用于访问真实的DOM节点,或者React组件的实例对象,允许直接操作DOM元素或者是组件;

写法

javascript 复制代码
const inpRef = useRef(params)

参数:
useRef(params),接收的 params 可以是任意类型的数据,初始值 在React首次 渲染中会被忽略
返回值inpRef,是一个包含 current 属性的对象,每次修改更新都会返回包含该属性的对象;

1、表单中直接通过 inpRef.current 修改

javascript 复制代码
import { useRef  } from 'react'
export default function MyRef() {
    const inpRef = useRef(null)
    console.log('==render=')
    const handleSearch = () => {
        console.log('==inpRef==', inpRef)
        inpRef.current.value = inpRef.current.value - 0  + 1
        console.log('==value=', inpRef.current.value)
    }
    return (
        <div>
            <input className="inp" ref={inpRef}></input><button onClick={handleSearch}>搜索</button>
            <hr />
            <button>{inpRef?.current?.value || '初始值'}</button>
        </div>
    )
}

通过log日志可以看出来:
render 只有在初始化渲染 时候才会打印,而当点击 搜索 按钮进行累加 input的值时候,只有input输入框中的值变化了 ,button 按钮中的值依然是 "初始值" 三个字;

2、直接操作DOM事件

可以直接访问自身组件中的事件,但是不允许访问其它组件的事件,即使是子组件事件也不行,因为React设计的 Refs 是一种脱围机制,访问其它组件的事件,会使组件本身变得不那么稳定健壮;可以使用forwardRef 访问到子组件的事件

javascript 复制代码
import { useRef  } from 'react'
export default function MyRef() {
    const inpRef = useRef(null)
     const handleSearch = () => {
        console.log('==inpRef==', inpRef)
        inpRef.current.focus()
    }
 return (
        <div>
            <input className="inp" ref={inpRef}></input><button onClick={handleSearch}>搜索</button>
        </div>
    )
}

useRef 返回值 ,可以直接操作input 原生事件,如focus、blur、change;vidoe视频的播放play、暂停pause

3、访问子组件事件

需要使用 forwardRef 和 useImperativeHandle

通过useImperativeHandle 在子组件暴露出父组件需要访问的属性或方法,类似与vue3 中的defineExpose()

javascript 复制代码
// 父组件
import { useRef, useEffect  } from 'react'
import Child from './child'
export default function MyRef() {
    const childRef = useRef(null)
    console.log('==render=')
    const handleGetChild = () => {
        console.log('==childRef==', childRef)
        childRef.current.handleChange()
        childRef.current.myfocus()
    }
    
    return (
        <div>
            <button onClick={handleGetChild}>获取子组件</button>
            <hr />
            <Child ref={childRef} ></Child>
        </div>
    )
}
javascript 复制代码
// 子组件
import { forwardRef, useRef, useImperativeHandle } from 'react'
// 使用 forwardRef 让组件使用 ref 将 DOM 节点暴露给父组件
const ChildInp =  forwardRef(({value}, ref) =>{
    // 定义当前组件中 input 的ref
    const inputRef = useRef(null);
    const handleChange = (data) => {
        console.log('==handleChange=', data)
    }
    // 只暴露 父组件需要的属性方法
    useImperativeHandle(ref, () => {
        console.log('=ref=8888=', inputRef)
        return {
            handleChange,
            myfocus(){
                inputRef.current.focus()
            }
        }
    }, [])
    return (
      <div>
        <p>Child 组件:</p>
         <input
            value={value}
            onChange={handleChange}
            ref={inputRef}
            />
      </div>
    )
  }) 

  export default ChildInp

用途:

1、直接操作DOM:可以通过 inpRef 来访问真实DOM,进而操作原生DOM的一些增删改查、颜色位置等操作;

2、访问组件的方法属性 :有时我们需要在父组件直接访问子组件的属性方法,可以结合forwardRef 访问到子组件的方法;

3、获取组件的实例或者事件进行监听

注意事项:

1、inpRef.current 是可以直接修改 的,但是它的修改不会触发视图的变更 ;

2、在视图更新渲染期间 ,不要尝试读写inpRef.current,这样会导致组件的行为难以捕捉;可以在 事件处理程序或者 Effect 中读取和写入 ref。

3、inpRef 可以在重新渲染直接存储信息,普通的对象每次重新渲染会将信息重置

4、谨慎使用 useRef 访问DOM的操作,尽可能使用数据驱动操作,触发现有方案无法满足,才使用useRef访问DOM

相关推荐
AI多Agent协作实战派18 分钟前
AI多Agent协作系统实战(二十三):Agent读HEARTBEAT.md不读AGENTS.md——openclaw的文件加载之谜
前端·数据库·人工智能·uni-app
gis开发之家34 分钟前
《Vue3 从入门到大神37篇》Vue3 源码详解(七):watch 与 watchEffect 源码对比——副作用是如何被追踪的?
javascript·前端框架·vue3·vue3源码
2601_955760071 小时前
如何用 Claude Opus 5 API 批量扩展长尾关键词和文章选题
前端·python·搜索引擎
KaMeidebaby1 小时前
卡梅德生物技术快报|bli亲和力检测gst:告别批量跑胶:BLI实时酶切监测技术加速GST融合蛋白下游流程优化
前端·网络·数据库·人工智能·算法
bloglin999992 小时前
langchain 和 langgraph 和 react
javascript·react.js·langchain
触底反弹2 小时前
🚀 删了数据刷新又回来?3 组件 × 4 回调 × 3 坑讲透 React 父子通信
前端·javascript·react.js
耳东小鹿3 小时前
对象常用方法
前端
程序员海军3 小时前
一个 AI 应用开发程序员的一天,都在屏幕前忙些什么?
前端·后端·程序员
moMo3 小时前
状态管理第一步:React useState 核心行为完全拆解
react.js
程序员黑豆3 小时前
鸿蒙应用开发:Stack堆叠组件实战——实现微信消息角标效果
前端·harmonyos