React函数式组件值之useRef()和useImperativeHandle()
一、useRef
useRef共有两种用法,获取子组件的实例(只有类组件可用),在函数组件中的一个全局变量,不会因为重复 render 重复申明, 类似于类组件的 this.xxx。
1. useRef 在使用的时候,可以传入默认值来指定默认值,需要使用的时候,访问 ref.current 即可访问到组件实例:
// 使用 ref 子组件必须是类组件
class Children extends PureComponent {
render () {
const { count } = this.props
return (
<div>{ count }</div>
)
}
}
function App () {
const [ count, setCount ] = useState(0)
const childrenRef = useRef(null)
const onClick = useMemo(() => {
return () => {
console.log(childrenRef.current)
setCount((count) => count + 1)
}
}, [])
return (
<div>
点击次数: { count }
<Children ref={childrenRef} count={count}></Children>
<button onClick={onClick}>点我</button>
</div>
)
}
2. 有些情况下,我们需要保证函数组件每次 render 之后,某些变量不会被重复申明,比如说 Dom 节点,定时器的 id 等等,在类组件中,我们完全可以通过给类添加一个自定义属性来保留,比如说 this.xxx, 但是函数组件没有 this,自然无法通过这种方法使用,有的朋友说,我可以使用useState 来保留变量的值,但是 useState 会触发组件 render,在这里完全是不需要的,我们就需要使用 useRef 来实现了,具体看下面例子:
function App () {
const [ count, setCount ] = useState(0)
const timer = useRef(null)
let timer2
useEffect(() => {
let id = setInterval(() => {
setCount(count => count + 1)
}, 500)
timer.current = id
timer2 = id
return () => {
clearInterval(timer.current)
}
}, [])
const onClickRef = useCallback(() => {
clearInterval(timer.current)
}, [])
const onClick = useCallback(() => {
clearInterval(timer2)
}, [])
return (
<div>
点击次数: { count }
<button onClick={onClick}>普通</button>
<button onClick={onClickRef}>useRef</button>
</div>
)
}
二、useImperativeHandle
useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值,说简单点就是,子组件可以选择性的暴露给副组件一些方法,这样可以隐藏一些私有方法和属性,官方建议,useImperativeHandle应当与 forwardRef 一起使用,具体如何使用看下面例子
function Child (props, ref) {
const child = useRef()
const introduce = useCallback (() => {
console.log('i can sing, jump, rap, play basketball')
}, [])
useImperativeHandle(ref, () => ({introduce}));
return (
<div ref={child}> { props.count }</div>
)
}
const ChildChild = forwardRef(Child)
function App () {
const [ count, setCount ] = useState(0)
const childRef = useRef(null)
const onClick = useCallback (() => {
setCount(count => count + 1)
childRef.current.introduce()
}, [])
return (
<div>
点击次数: { count }
<ChildChild ref={childRef} count={count}></ChildChild>
<button onClick={onClick}>点我</button>
</div>
)
}
React函数式组件值之useRef()和useImperativeHandle()的更多相关文章
- 如何对 React 函数式组件进行优化
文章首发个人博客 前言 目的 本文只介绍函数式组件特有的性能优化方式,类组件和函数式组件都有的不介绍,比如 key 的使用.另外本文不详细的介绍 API 的使用,后面也许会写,其实想用好 hooks ...
- React 函数式组件的 Ref 和子组件访问(useImperativeHandle)
引入:如何调用函数式组件内部的方法 对于 React 中需要强制修改子组件的情况,React 提供了 Refs 这种解决办法,使得我们可以操作底层 DOM 元素或者自定的 class 组件实例.除此之 ...
- React函数式组件使用Ref
目录: 简介 useRef forwardRef useImperativeHandle 回调Ref 简介 大家都知道React中的ref属性可以帮助我们获取子组件的实例或者Dom对象,进而对子组件进 ...
- React函数式组件和类组件[Dan]
一篇对Dan的 How Are Function Components Different from Classes? 一文的个人阅读总结,内容来自于此.强烈推荐阅读 Dan Abramov.的博客. ...
- React函数式组件的性能优化
优化思路 主要优化的方向有2个: 减少重新 render 的次数.因为在 React 里最重(花时间最长)的一块就是 reconction(简单的可以理解为 diff),如果不 render,就不会 ...
- 函数式组件中实现Antd打开Modal后其Input框自动聚焦(focus)到文字的最后
目前React使用函数式组件已经成为趋势, 如何把React函数式组件用好, 提高性能, 从而实现业务需求也成为了一种能力的体现......咳咳咳, 进入正题: 现实场景需求 我想实现这一个需求, 父 ...
- react 中的无状态函数式组件
无状态函数式组件,顾名思义,无状态,也就是你无法使用State,也无法使用组件的生命周期方法,这就决定了函数组件都是展示性组件,接收Props,渲染DOM,而不关注其他逻辑. 其实无状态函数式组件也是 ...
- React Native组件、生命周期及属性传值props详解
创建组件的三种方式 第一种:通过ES6的方式创建 /** * 方式一 :ES6 */ export default class HelloComponent extends Component { r ...
- React 学习(一) ---- React Element /组件/JSX
学习React的时候,你可能听到最多的就是要先学习webpack, babel,要先学会配置然后才能学react 等等,一堆的配置就把我们吓着了,根本就没有心情就学习react了.其实在最开始学习re ...
- beeshell —— 开源的 React Native 组件库
介绍 beeshell 是一个 React Native 应用的基础组件库,基于 0.53.3 版本,提供一整套开箱即用的高质量组件,包含 JavaScript(以下简称 JS)组件和复合组件(包含 ...
随机推荐
- 使用vue创建一个吸顶的菜单项--简单版
1.hover时候出现,总体来说只改了一下两个index.vue,还有route文件 src\layoutTwo\index.vue <template> <div class=&q ...
- Angularjs的重要概念
AngularJS的重要概念 MVC模式 AngularJS最早按照MVC模式设计,在这种设计模式下,AngularJS组件可以分为: M: Model,即模型,是应用程序中用于处理应用程序数据逻辑的 ...
- vue学习笔记(四)---- 品牌管理案例
一.导入相关包 <script src="../lib/vue2.6.10.min.js"></script> <script src=". ...
- Nacos配置中心 (介绍与配置)
Nacos配置中心 当微服务部署的实例越来越多,达到数十.数百时,逐个修改微服务配置就会让人抓狂,而且很容易出错.我们需要一种统一配置管理方案,可以集中管理所有实例的配置. Nacos一方面可以将配置 ...
- 2023.1.16[模板]BSGS/exBSGS
2023.1.16 [模板]BSGS/exBSGS 全称Boy Step Girl Step 给定一个质数 p,以及一个整数 a,一个整数 b,现在要求你计算一个最小的非负整数 l, 满足\(a^x ...
- Arm-Linux子系统的互相Notify
前言: Linux下面不同的子系统一个个的组成了整个系统的运行环节,为了让这些子系统能够互相通讯,有一种叫做:notify chain(通知链)的东西.本篇看下. 概括 所谓通知链,有通知,就有执行的 ...
- KMP 算法 再次学习
c++ 版后面再补 package cn.kbug.dynamic; import java.util.Arrays; /** * KMP 算法本质上是对 搜索的字符串做优化,然后在匹配的时候,能做到 ...
- Redis-03 数据格式和基础命令
1 单进程 Redis采用单进程模型来处理客户端的请求.对读写等时间的响应是通过对epoll函数的包装来做到的.Redis的实际处理速度完全依靠主进程的执行效率. Epoll是Linux内核为 ...
- spring cloud alibaba Nacos集群部署 Linux
参考:https://www.cnblogs.com/dw3306/p/12961353.html 1.官网: https://nacos.io/zh-cn/docs/cluster-mode- ...
- go语言面试
go面试 基础 = 和 := 的区别? **Go语言中,= 操作符用于赋值,而 := 操作符可以用于声明及赋值. Go 语言支持短变量声明(针对局部变量),以 := 为标志,这里要注意的是,Go 语言 ...