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. react中redux的理解

    定义 redux可以看作是flux的进阶版,主要用于react中公共状态(数据)的管理 redux底层原理 redux有一个createStore方法,这个方法用户创建公共存储空间,createSto ...

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

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

  4. react中refs详解

    https://zh-hans.reactjs.org/docs/refs-and-the-dom.html 字符串形式ref 1 <input ref="myinput" ...

  5. react中super()的理解

    首先 super() 是在 es6的class(类)的方法创建组件出现 下面是分别是构造函数创建组件和class(类)创建组件 构造函数方法创建组件 在构造函数方法中,在组件接收参数的时候,props ...

  6. React中refs持久化

    根据使用React的版本,选择合适的方法. 字符串模式 :废弃不建议使用 回调函数,React版本 < 16.3 React.createRef() :React版本 >= 16.3 回调 ...

  7. react中Hooks的理解和用法

    一.Hooks是什么? Hook 是 React 16.8 的新增特性.它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性 至于为什么引入hook,官方给出的动机是 ...

  8. 对于react中rredux的理解

    1.什么是redux? redux是一个应用数据流框架,主要作用是对于应用状态的管理 2.reducer特点 : (1)默认的state (2)state是只可读不可修改 (3)必须返回一个纯函数 3 ...

  9. react中的setState的使用和深入理解

    前端框架从MVC过渡到MVVM.从DOM操作到数据驱动,一直在不断的进步着,提升着, angular中用的是watcher对象,vue是观察者模式,react就是state了,他们各有各的特点,没有好 ...

  10. 深入理解react中的虚拟DOM、diff算法

    文章结构: React中的虚拟DOM是什么? 虚拟DOM的简单实现(diff算法) 虚拟DOM的内部工作原理 React中的虚拟DOM与Vue中的虚拟DOM比较 React中的虚拟DOM是什么?   ...

随机推荐

  1. http-自签证书

    1. 背景 证书需要向云服务提供商购买,是需要付费,但用在应用开发场景是不合适的,需要开发者自己自签证书进行测试 2. 工具包 Cygwin a large collection of GNU and ...

  2. [转帖]nginx源码层面探究request_time、upstream_response_time、upstream_connect_time与upstream_header_time指标具体含义与区别

    https://www.cnblogs.com/AcAc-t/p/nginx_request_time_upstream_respone_time_analysis.html 背景概述 最近计划着重分 ...

  3. [转帖]shell编程之条件语句

    目录 一.条件测试 test命令 文件测试与整数测试 文件测试 整数值比较 字符串测试与逻辑测试 字符串比较 逻辑测试 二.if语句 if单分支语句 单分支结构 if双分支语句 双分支结构 if多分支 ...

  4. CPU算力提升与实际性能提升的关系

    关于SPEC2006CPU和RedisBenchmark的理解 最近研究过硬件CPU的性能和Redis这样单线程重IO服务 突然想对比一下CPU算力提升占Redis性能提升的比率情况 性能很大程度由C ...

  5. 让你轻松看懂defer和async

    defer和async产生的原因 HTML 网页中,浏览器通过<script>标签加载 JavaScript 脚本. <!-- 页面内嵌的脚本 --> <script t ...

  6. 【代码片段】fasthttp 中的输出使用 gzip 压缩

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 直接上代码: import ( "github. ...

  7. ABP-VNext 用户权限管理系统实战03---动态api调用并传递token

    一.使用动态api的目的 ABP可以自动创建C# API 客户端代理来调用远程HTTP服务(REST APIS).通过这种方式,你不需要通过 HttpClient 或者其他低级的HTTP功能调用远程服 ...

  8. Gin 框架介绍与快速入门

    Gin 框架介绍与快速入门 目录 Gin 框架介绍与快速入门 一.Gin框架介绍 1. 快速和轻量级 2. 路由和中间件 3. JSON解析 4. 支持插件 5. Gin相关文档 二.基本使用 1.安 ...

  9. 3.6 Windows驱动开发:内核进程汇编与反汇编

    在笔者上一篇文章<内核MDL读写进程内存>简单介绍了如何通过MDL映射的方式实现进程读写操作,本章将通过如上案例实现远程进程反汇编功能,此类功能也是ARK工具中最常见的功能之一,通常此类功 ...

  10. RabbitMQ高级知识(消息可靠性,死信交换机,惰性队列,MQ集群)

    服务异步通信-高级篇 消息队列在使用过程中,面临着很多实际问题需要思考: 1.消息可靠性 消息从发送,到消费者接收,会经历多个过程: 其中的每一步都可能导致消息丢失,常见的丢失原因包括: 发送时丢失: ...