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. 战略设计- DDD

    随着系统的增长,它会变得越来越复杂,当我们无法通过分析对象来理解系统的时候,就需要掌握一些操纵和理解大模型的技术了.本文将介绍一些原则.遵循这些原则,就可以对非常复杂的领域进行建模.大部分这样的决策都 ...

  2. JDBC针对SQLServer的sendStringParametersAsUnicode=false的验证

    JDBC针对SQLServer的sendStringParametersAsUnicode=false的验证 背景 部分客户的SQLServer数据库出现了大量死锁的情况. 虽然部分客户并没有反馈死锁 ...

  3. [转帖]Spring Cloud 整合 SkyWalking

    https://www.jianshu.com/p/e81e35dc6406 Java Agent 服务器探针 探针,用来收集和发送数据到归集器.参考官网给出的帮助 Setup java agent, ...

  4. 【转帖】Dockerfile文件指令介绍

    https://blog.whsir.com/post-5327.html Dockerfile其实就是一个文本文件,这个文本文件名称叫Dockerfile,里面包含了一些指令(可以理解成多个指令集合 ...

  5. [转帖]C2C - False Sharing Detection in Linux Perf

    https://joemario.github.io/blog/2016/09/01/c2c-blog/ Do you run your application in a NUMA environme ...

  6. [官网]Apache Log4j2 最新版安全提示 2.17.0

    https://logging.apache.org/log4j/2.x/ 最近一个周的时间 log4j2 从 2.14 跃升到了2.17 还在不停的升级 安全问题正是焦头烂额 free softwa ...

  7. CS231N Assignment1 softmax 笔记

    -为Softmax分类器实现完全矢量化的损失函数 -实现解析梯度完全矢量化的表达式 使用数值梯度检查实现结果 使用验证集调整学习率和正则化强度 使用SGD优化损失函数 可视化最终学习的权重 softm ...

  8. git中 commit 和 pull 的先后顺序问题会产生多余的merge记录

    commit 和 pull 的先后顺序问题 最近提交代码,发现一个问题. 自己很清楚的记得本次的提交是没有进行合并的. 奇怪的死 gitlab中的 history 历史中显示了我对本次进行了Merge ...

  9. Ant Design Vue 单文件上传Upload

    单文件上传 <a-upload name="file" :beforeUpload="beforeUpload" :multiple="fals ...

  10. 发布.net core应用程序并部署到IIS上

    一.在项目里右击选择发布点击启动配置如下图所示 二.在打开的发布选项选择 配置 Release或DeBug ,目标框架选择对应的.net Core版本默认就行,部署模式有两种选择 1.框架依赖---- ...