React中refs的理解

Refs提供了一种方式,允许我们访问DOM节点或在render方法中创建的React元素。

描述

在典型的React数据流中,props是父组件与子组件交互的唯一方式,要修改一个子组件,你需要使用新的props来重新渲染它,但是在某些情况下,你需要在典型数据流之外强制修改子组件,被修改的子组件可能是一个React组件的实例,也可能是一个DOM元素,对于这两种情况React都提供了解决办法。
避免使用refs来做任何可以通过声明式实现来完成的事情,通常在可以使用propsstate的情况下勿依赖refs,下面是几个适合使用refs的情况:

  • 管理焦点、文本选择或媒体播放。
  • 触发强制动画。
  • 集成第三方DOM库。

使用

React提供的这个ref属性,表示为对组件真正实例的引用,其实就是ReactDOM.render()返回的组件实例,需要区分一下渲染组件与渲染原生DOM元素,渲染组件时返回的是组件实例,而渲染DOM元素时,返回是具体的DOM节点,Reactref3种用法。

字符串

ref可以直接设置为字符串值,这种方式基本不推荐使用,或者在未来的React版本中不会再支持该方式。这主要是因为使用字符串导致的一些问题,例如当ref定义为string时,需要React追踪当前正在渲染的组件,在reconciliation阶段,React Element创建和更新的过程中,ref会被封装为一个闭包函数,等待commit阶段被执行,这会对React的性能产生一些影响等。

class InputOne extends React.Component {componentDidMount() {this.refs.inputRef.value = 1;}render() {return <input ref="inputRef" />;}
}

回调

React支持给任意组件添加特殊属性,ref属性接受一个回调函数,其在组件被加载或卸载时会立即执行。

  • 当给HTML元素添加ref属性时,ref回调接收了底层的DOM元素作为参数。
  • 当给组件添加ref属性时,ref回调接收当前组件实例作为参数。
  • 当组件卸载的时候,会传入null
  • ref回调会在componentDidMountcomponentDidUpdate等生命周期回调之前执行。

Callback Ref我们通常会使用内联函数的形式,那么每次渲染都会重新创建,由于React会清理旧的ref然后设置新的,因此更新期间会调用两次,第一次为null,如果在Callback中带有业务逻辑的话,可能会出错,可以通过将Callback定义成类成员函数并进行绑定的方式避免。

class InputTwo extends React.Component {componentDidMount() {this.inputRef.value = 2;}render() {return <input ref={(element) =>this.inputRef = element} />;}
}

API创建

React v16.3中经0017-new-create-ref提案引入了新的React.createRefAPI,当ref被传递给render中的元素时,对该节点的引用可以在refcurrent属性中被访问,ref的值根据节点的类型而有所不同:

  • ref属性用于HTML元素时,构造函数中使用React.createRef()创建的ref接收底层DOM元素作为其current属性。
  • ref属性用于自定义class组件时,ref对象接收组件的挂载实例作为其current属性。
  • 不能在函数组件上使用ref属性,因为他们没有实例。

对比新的CreateRefCallback Ref,并没有压倒性的优势,只是希望成为一个便捷的特性,在性能上会会有微小的优势,Callback Ref采用了组件Render过程中在闭包函数中分配ref的模式,而CreateRef则采用了Object Ref

class InputThree extends React.Component {constructor(props) {super(props);this.inputRef = React.createRef();}componentDidMount() {this.inputRef.current.value = 3;}render() {return <input ref={this.inputRef} />;}
}

示例

<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>React</title>
</head><body><div id="root"></div>
</body>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">class InputOne extends React.Component {componentDidMount() {this.refs.inputRef.value = 1;}render() {return <input ref="inputRef" />;}}class InputTwo extends React.Component {componentDidMount() {this.inputRef.value = 2;}render() {return <input ref={(element) =>this.inputRef = element} />;}}class InputThree extends React.Component {constructor(props) {super(props);this.inputRef = React.createRef();}componentDidMount() {this.inputRef.current.value = 3;}render() {return <input ref={this.inputRef} />;}}var vm = ReactDOM.render(<><InputOne /><InputTwo /><InputThree /></>,document.getElementById("root"));
</script></html>

每日一题

https://github.com/WindrunnerMax/EveryDay

参考

https://zhuanlan.zhihu.com/p/40462264
https://www.jianshu.com/p/4e2357ea1ba1
https://juejin.cn/post/6844903809274085389
https://juejin.cn/post/6844904048882106375
https://segmentfault.com/a/1190000008665915
https://zh-hans.reactjs.org/docs/refs-and-the-dom.html

React中refs的理解相关推荐

  1. React中JSX的理解

    React中JSX的理解 JSX是快速生成react元素的一种语法,实际是React.createElement(component, props, ...children)的语法糖,同时JSX也是J ...

  2. Vue中$refs的理解

    Vue中$refs的理解 $refs是一个对象,持有注册过ref attribute的所有DOM元素和组件实例. 描述 ref被用来给元素或子组件注册引用信息,引用信息将会注册在父组件的$refs对象 ...

  3. React 中 refs 的作用是什么?

    Refs 是 React 提供给我们的安全访问 DOM 元素或者某个组件实例的句柄. 我们可以为元素添加 ref 属性然后在回调函数中接受该元素在 DOM 树中的句柄,该值会作为回调函数的第一个参数返 ...

  4. React中ref的理解

    (1)React的ref有3种用法: 字符串 dom节点上使用,通过this.refs[refName]来引用真实的dom节点 <input ref="inputRef" / ...

  5. React开发(211):react中refs转发到dom组件

  6. 彻底理解react中的props

    每天对自己多问几个为什么,总是有着想象不到的收获. 一个菜鸟小白的成长之路(copyer) ​在react中 state 和 props是两个非常重要的属性,并且常用的属性.简单来说:都是用来保存数据 ...

  7. 关于react中setState的深入理解

    在react中,通常通过state或props,来控制整个组件的状态.一旦state或props发生改变,整个组件会被重新渲染.在setState的理解上,可能会存在一些误区. setState的基本 ...

  8. [react] react中可以在render访问refs吗?为什么?

    [react] react中可以在render访问refs吗?为什么? <><span id="name" ref={this.spanRef}>{this ...

  9. [react] 说说你对“在react中,一切都是组件”的理解

    [react] 说说你对"在react中,一切都是组件"的理解 React采用组件化的思想,最小的组件单位就是原生HTML元素,采用JSX的语法声明组件的调用 React的虚拟DO ...

最新文章

  1. 身份证号信息后台匹配
  2. XShell与虚拟机连接的IP问题
  3. 数学--数论--莫比乌斯反演
  4. java实现验证码3秒刷新一次
  5. k8s部署tomcat及web应用_部署 Spring Boot 应用到 K8S 教程
  6. Oracle RAC更改VIP IP地址_2节点的实验
  7. 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes
  8. 为5—18岁青少年提供营地教育,漫族完成百万级天使轮融资
  9. 技巧收藏|10个JavaScript常用数组操作方法
  10. jquery为元素绑定事件
  11. mysql 默认事务隔离级别_一文读懂MySQL的事务隔离级别及MVCC机制
  12. C语言动态库libxxx.so的几种使用方法
  13. NSLog 打印出方法函数,行数,内容
  14. Spring官网改版后下载
  15. Log4j日志使用记录
  16. Uva 10061 进制问题
  17. Python将字符串转换为列表
  18. 计算机软考高级论文怎么写,计算机软考高级论文
  19. Java实习 oneday
  20. 如何开展系统安全测试

热门文章

  1. Kubernetes群集的零停机服务器更新
  2. Php数组面包屑导航,thinkphp实现面包屑导航(当前位置)例子分享
  3. 基于CentOS7,MySQL5.7的主从复制架构搭建实战
  4. 云计算中的Iaas,Paas和Saas
  5. C#组件系列——又一款Excel处理神器Spire.XLS,你值得拥有
  6. 物联网进入规模化应用时代 万物互联时代到来
  7. 现实世界的Windows Azure:与iQmetrix的市场营销副总裁Anne Weiler对话
  8. 当下的力量 - [读书笔记]
  9. 2011年4月51CTO壁纸点评活动获奖名单【已结束】
  10. 中文VS2008安装ASP.NET MVC框架解决方案