当前位置: 首页 > news >正文

react hooks之useRef和useImperativeHandle

为什么这两个一起写,是因为这两个关联性很大,逐一介绍。

一:useRef

1、作用:用于在函数组件中创建一个持久化的引用变量。这个引用变量可以在组件的多次渲染之间保持不变,并且可以访问和修改 DOM 元素或其他组件实例的实例变量。

2、示例

import React, { useState, useRef } from 'react';function TextInput() {const [value, setValue] = useState('');const inputRef = useRef(null);function focusInput() {inputRef.current.focus();}return (<div><input type="text" value={value} onChange={(e) => setValue(e.target.value)} ref={inputRef} /><button onClick={focusInput}>Focus Input</button></div>);
}function App() {return <TextInput />;
}

在这个示例中,我们首先使用 useState Hook 创建了一个名为 value 的状态变量,它保存了输入框中的值。然后,我们使用 useRef Hook 创建了一个名为 inputRef 的引用变量,并将其初始化为 null

在输入框标签中,我们使用了 ref={inputRef} 属性将 inputRef 和输入框绑定起来。这样,我们就可以在组件中的其他地方访问和修改输入框元素的属性。

focusInput 函数中,我们使用了 inputRef.current 来获取输入框元素,并调用了 focus() 方法来聚焦输入框。

最后,在 TextInput 组件中,我们渲染了一个输入框和一个按钮。当用户点击按钮时,它会调用 focusInput 函数,将焦点聚焦到输入框上。

这是 useRef 的基本用法。通过使用 useRef,你可以在函数组件中创建一个持久化的引用变量,并访问和修改 DOM 元素或其他组件实例的实例变量。

(示例2)

import React, { useEffect, useRef } from 'react';function Timer() {const timerRef = useRef(null);useEffect(() => {// 在组件挂载时启动定时器timerRef.current = setInterval(() => {console.log('Timer tick');}, 1000);// 在组件卸载时清除定时器return () => {clearInterval(timerRef.current);};}, []);return (<div><h1>Timer</h1></div>);
}function App() {return <Timer />;
}

在这个示例中,我们使用 useRef 创建了一个名为 timerRef 的引用变量,并将其初始化为 null

useEffect 钩子中,我们使用 timerRef.current 来获取当前的定时器引用。当组件挂载时,我们通过 setInterval 创建一个定时器,并将其赋值给 timerRef.current。定时器每隔一秒钟输出 "Timer tick"。

同时,我们还在 useEffect 中返回一个清理函数,它会在组件卸载时执行。在清理函数中,我们使用 clearInterval 来清除定时器,以防止内存泄漏。

最后,在 Timer 组件中,我们渲染了一个标题标签。但重点是,我们在组件的生命周期方法中使用了 useEffectuseRef 来启动和清除定时器。

这是另一个 useRef 的例子,展示了它如何用于在函数组件中引用和管理副作用.

3、总结:

通过上面两个示例,可以了解到,useref有两个作用:

1、保存 DOM 元素的引用:获取组件的属性等操作

2、缓存组件状态:简单的理解为,和usestate不同的是,useRef 返回的 ref 对象可以在组件的每次渲染过程中保持不变,即使组件重新渲染,它也不会被重新赋值。

二、useImperativeHandle

1、作用:用于在函数组件中自定义向父组件暴露的实例值和方法。通常情况下,React 推荐使用 props 来进行组件之间的通信,但有时候我们可能需要在函数组件中使用类似于 Class 组件中的实例方法和属性。

2、用法:useImperativeHandle 接受两个参数:ref 和一个回调函数。回调函数会接收一个参数,即父组件传递给子组件的 ref 对象。在回调函数中,我们可以定义这个 ref 对象所暴露出来的实例值和方法。

3、示例

import React, { useRef, useImperativeHandle, forwardRef } from 'react';const ChildComponent = forwardRef((props, ref) => {const inputRef = useRef();useImperativeHandle(ref, () => ({focus: () => {inputRef.current.focus();},getValue: () => {return inputRef.current.value;}}));return <input type="text" ref={inputRef} />;
});function ParentComponent() {const childRef = useRef();function handleClick() {childRef.current.focus();const value = childRef.current.getValue();console.log('Input value:', value);}return (<div><ChildComponent ref={childRef} /><button onClick={handleClick}>Focus Input and Get Value</button></div>);
}

上面的示例中,我们创建了一个 ChildComponent 组件,并使用 useRef 声明了一个 childRef 引用。然后,在 useImperativeHandle 的回调函数中,我们定义了要向父组件暴露的两个实例方法:focusgetValue。在 focus 方法中,我们通过 childRef.current 来访问子组件的 DOM 元素,并使其获取焦点。在 getValue 方法中,我们同样通过 childRef.current 来获取子组件输入框的值。

在父组件中,我们使用 React.forwardRef 包裹了 ChildComponent,以便能够接收父组件传递的 ref。然后,我们创建了一个 childRef 引用,将其传递给 ForwardedChildComponent。当点击按钮时,我们调用 childRef.current 上的 focus 方法和 getValue 方法,并输出输入框的值。

总结:子组件想暴露给父组件什么完全由子组件决定。和vue中的ref不同。

http://www.lryc.cn/news/257917.html

相关文章:

  • scala方法与函数
  • 前端框架(Front-end Framework)和库(Library)的区别
  • mysql原理--B+树索引的使用
  • Android : Room 数据库的基本用法 —简单应用_三_版本
  • 微服务网关组件Gateway实战
  • 目标检测YOLO系列从入门到精通技术详解100篇-【目标检测】三维重建(补充篇)
  • 关于uniapp X 的最新消息
  • spark从表中采样(随机选取)一定数量的行
  • java定位系统源码,UWB技术的无线定位系统源码
  • 阿里云sls日志服务如何查某个具体字段的平均数
  • Java八股文面试全套真题【含答案】- Maven篇
  • 从零构建属于自己的GPT系列6:模型本地化部署2(文本生成函数解读、模型本地化部署、文本生成文本网页展示、代码逐行解读)
  • 不同品牌的手机如何投屏到苹果MacBook?例如小米、华为怎样投屏比较好?
  • 路由和网络周期
  • 【算法与数据结构】332、LeetCode重新安排行程
  • 阶段五:深度学习和人工智能(掌握使用TensorFlow或PyTorch进行深度学习)
  • DevEco Studio IDE 创建项目时候配置环境
  • HTML面试题---专题二
  • K12484 银行排队(bank)
  • JAVA实操经验
  • 微信小程序 ios 手机底部安全区适配
  • ReetrantReadWriteLock底层原理
  • LeetCode力扣每日一题(Java):35、搜索插入位置
  • Unity中结构体定义的成员如何显示在窗口中
  • Python3开发环境的搭建
  • Leetcode 2957. Remove Adjacent Almost-Equal Characters
  • 透析跳跃游戏
  • 贵州开放大学形成性考核 平时作业 参考试题
  • Leetcode 2962. Count Subarrays Where Max Element Appears at Least K Times
  • Mybatis XML 配置文件