一、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()的更多相关文章

  1. 如何对 React 函数式组件进行优化

    文章首发个人博客 前言 目的 本文只介绍函数式组件特有的性能优化方式,类组件和函数式组件都有的不介绍,比如 key 的使用.另外本文不详细的介绍 API 的使用,后面也许会写,其实想用好 hooks ...

  2. React 函数式组件的 Ref 和子组件访问(useImperativeHandle)

    引入:如何调用函数式组件内部的方法 对于 React 中需要强制修改子组件的情况,React 提供了 Refs 这种解决办法,使得我们可以操作底层 DOM 元素或者自定的 class 组件实例.除此之 ...

  3. React函数式组件使用Ref

    目录: 简介 useRef forwardRef useImperativeHandle 回调Ref 简介 大家都知道React中的ref属性可以帮助我们获取子组件的实例或者Dom对象,进而对子组件进 ...

  4. React函数式组件和类组件[Dan]

    一篇对Dan的 How Are Function Components Different from Classes? 一文的个人阅读总结,内容来自于此.强烈推荐阅读 Dan Abramov.的博客. ...

  5. React函数式组件的性能优化

    优化思路 主要优化的方向有2个: 减少重新 render 的次数.因为在 React 里最重(花时间最长)的一块就是 reconction(简单的可以理解为 diff),如果不 render,就不会 ...

  6. 函数式组件中实现Antd打开Modal后其Input框自动聚焦(focus)到文字的最后

    目前React使用函数式组件已经成为趋势, 如何把React函数式组件用好, 提高性能, 从而实现业务需求也成为了一种能力的体现......咳咳咳, 进入正题: 现实场景需求 我想实现这一个需求, 父 ...

  7. react 中的无状态函数式组件

    无状态函数式组件,顾名思义,无状态,也就是你无法使用State,也无法使用组件的生命周期方法,这就决定了函数组件都是展示性组件,接收Props,渲染DOM,而不关注其他逻辑. 其实无状态函数式组件也是 ...

  8. React Native组件、生命周期及属性传值props详解

    创建组件的三种方式 第一种:通过ES6的方式创建 /** * 方式一 :ES6 */ export default class HelloComponent extends Component { r ...

  9. React 学习(一) ---- React Element /组件/JSX

    学习React的时候,你可能听到最多的就是要先学习webpack, babel,要先学会配置然后才能学react 等等,一堆的配置就把我们吓着了,根本就没有心情就学习react了.其实在最开始学习re ...

  10. beeshell —— 开源的 React Native 组件库

    介绍 beeshell 是一个 React Native 应用的基础组件库,基于 0.53.3 版本,提供一整套开箱即用的高质量组件,包含 JavaScript(以下简称 JS)组件和复合组件(包含 ...

随机推荐

  1. shell基础命令知识持续更新

    查看系统支持的shell cat /etc/shells [root@iZwz9almo8p830btq7voo9Z shellLearning]# cat /etc/shells /bin/sh / ...

  2. springcloud与微服务

    springcloud 与 微服务 父工程(按需导入依赖) <!--打包--> <packaging>pom</packaging> <properties& ...

  3. JSTL概述和JSTL常用标签if

    JSTL概述 1.概念:JavaServlet Pages Tag Library(JSP标准标签库) 是由Apache组织提供的开源的免费的jsp标签 <标签> 2.作用:用于简化和替换 ...

  4. Properties集合中的方法load-缓冲流的原理

    Properties集合中的方法load 参数:InputStream instream:字节输入流,不能读取含有中文的键值对Reader reader:字符输入流,能读取含有中文的键值对使用步骤:1 ...

  5. appium之安卓7.0环境搭建

    appium 在安卓7.0的手机上运行上报错---------Failure [INSTALL_FAILED_ALREADY_EXISTS: Attempt to re-install io.appi ...

  6. 高精度计算模板 -感谢acwing

    高精度加 1 // C = A + B, A >= 0, B >= 0 2 vector<int> add(vector<int> &A, vector&l ...

  7. CAS 悲观锁 乐观锁

    前面的偏向锁,轻量级锁,重量级锁都是悲观锁, 都会认为必须要对操作对象进行互斥访问,不然就会产生异常, 所以线程只供一个线程使用,阻塞其他线程,是悲观的 在某些情况下,同步的耗时远大于线程切换的时间, ...

  8. jsp传入servlet数据

    面对老师的19级期末,要用到jsp传入servlet的数据传输,借鉴了其他人的代码,以下是我的程序 jsp界面: <%request.getSession().setAttribute(&quo ...

  9. concurrent-map 和 sync.Map,我该选择哪个?

    concurrent-map 和 sync.Map,我该选择哪个? 官方的map并不是线程安全的,如果我们在多线程中并发对一个map进行读写操作,是会引发panic的.解决方案除了使用锁来对map进行 ...

  10. 手把手教你为基于Netty的IM生成自签名SSL/TLS证书

    1.引言 对于IM聊天应用来说,为了提升安全性,对聊天消息加密是常规操作. 众所周之,Netty是高性能的Java NIO网络通信框架,因而用Netty来写IM是再正常不过了.网上关于为Netty生成 ...