React中refs的理解
React中refs的理解
Refs
提供了一种方式,允许我们访问DOM
节点或在render
方法中创建的React
元素。
描述
在典型的React
数据流中,props
是父组件与子组件交互的唯一方式,要修改一个子组件,你需要使用新的props
来重新渲染它,但是在某些情况下,你需要在典型数据流之外强制修改子组件,被修改的子组件可能是一个React
组件的实例,也可能是一个DOM
元素,对于这两种情况React
都提供了解决办法。
避免使用refs
来做任何可以通过声明式实现来完成的事情,通常在可以使用props
与state
的情况下勿依赖refs
,下面是几个适合使用refs
的情况:
- 管理焦点、文本选择或媒体播放。
- 触发强制动画。
- 集成第三方
DOM
库。
使用
React
提供的这个ref
属性,表示为对组件真正实例的引用,其实就是ReactDOM.render()
返回的组件实例,需要区分一下渲染组件与渲染原生DOM
元素,渲染组件时返回的是组件实例,而渲染DOM
元素时,返回是具体的DOM
节点,React
的ref
有3
种用法。
字符串
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
回调会在componentDidMount
或componentDidUpdate
等生命周期回调之前执行。
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.createRef
的API
,当ref
被传递给render
中的元素时,对该节点的引用可以在ref
的current
属性中被访问,ref
的值根据节点的类型而有所不同:
- 当
ref
属性用于HTML
元素时,构造函数中使用React.createRef()
创建的ref
接收底层DOM
元素作为其current
属性。 - 当
ref
属性用于自定义class
组件时,ref
对象接收组件的挂载实例作为其current
属性。 - 不能在函数组件上使用
ref
属性,因为他们没有实例。
对比新的CreateRef
与Callback 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的理解的更多相关文章
- React中JSX的理解
React中JSX的理解 JSX是快速生成react元素的一种语法,实际是React.createElement(component, props, ...children)的语法糖,同时JSX也是J ...
- react中redux的理解
定义 redux可以看作是flux的进阶版,主要用于react中公共状态(数据)的管理 redux底层原理 redux有一个createStore方法,这个方法用户创建公共存储空间,createSto ...
- React 中 refs 的作用是什么?
Refs 是 React 提供给我们的安全访问 DOM 元素或者某个组件实例的句柄.我们可以为元素添加 ref 属性然后在回调函数中接受该元素在 DOM 树中的句柄,该值会作为回调函数的第一个参数返回 ...
- react中refs详解
https://zh-hans.reactjs.org/docs/refs-and-the-dom.html 字符串形式ref 1 <input ref="myinput" ...
- react中super()的理解
首先 super() 是在 es6的class(类)的方法创建组件出现 下面是分别是构造函数创建组件和class(类)创建组件 构造函数方法创建组件 在构造函数方法中,在组件接收参数的时候,props ...
- React中refs持久化
根据使用React的版本,选择合适的方法. 字符串模式 :废弃不建议使用 回调函数,React版本 < 16.3 React.createRef() :React版本 >= 16.3 回调 ...
- react中Hooks的理解和用法
一.Hooks是什么? Hook 是 React 16.8 的新增特性.它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性 至于为什么引入hook,官方给出的动机是 ...
- 对于react中rredux的理解
1.什么是redux? redux是一个应用数据流框架,主要作用是对于应用状态的管理 2.reducer特点 : (1)默认的state (2)state是只可读不可修改 (3)必须返回一个纯函数 3 ...
- react中的setState的使用和深入理解
前端框架从MVC过渡到MVVM.从DOM操作到数据驱动,一直在不断的进步着,提升着, angular中用的是watcher对象,vue是观察者模式,react就是state了,他们各有各的特点,没有好 ...
- 深入理解react中的虚拟DOM、diff算法
文章结构: React中的虚拟DOM是什么? 虚拟DOM的简单实现(diff算法) 虚拟DOM的内部工作原理 React中的虚拟DOM与Vue中的虚拟DOM比较 React中的虚拟DOM是什么? ...
随机推荐
- 战略设计- DDD
随着系统的增长,它会变得越来越复杂,当我们无法通过分析对象来理解系统的时候,就需要掌握一些操纵和理解大模型的技术了.本文将介绍一些原则.遵循这些原则,就可以对非常复杂的领域进行建模.大部分这样的决策都 ...
- JDBC针对SQLServer的sendStringParametersAsUnicode=false的验证
JDBC针对SQLServer的sendStringParametersAsUnicode=false的验证 背景 部分客户的SQLServer数据库出现了大量死锁的情况. 虽然部分客户并没有反馈死锁 ...
- [转帖]Spring Cloud 整合 SkyWalking
https://www.jianshu.com/p/e81e35dc6406 Java Agent 服务器探针 探针,用来收集和发送数据到归集器.参考官网给出的帮助 Setup java agent, ...
- 【转帖】Dockerfile文件指令介绍
https://blog.whsir.com/post-5327.html Dockerfile其实就是一个文本文件,这个文本文件名称叫Dockerfile,里面包含了一些指令(可以理解成多个指令集合 ...
- [转帖]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 ...
- [官网]Apache Log4j2 最新版安全提示 2.17.0
https://logging.apache.org/log4j/2.x/ 最近一个周的时间 log4j2 从 2.14 跃升到了2.17 还在不停的升级 安全问题正是焦头烂额 free softwa ...
- CS231N Assignment1 softmax 笔记
-为Softmax分类器实现完全矢量化的损失函数 -实现解析梯度完全矢量化的表达式 使用数值梯度检查实现结果 使用验证集调整学习率和正则化强度 使用SGD优化损失函数 可视化最终学习的权重 softm ...
- git中 commit 和 pull 的先后顺序问题会产生多余的merge记录
commit 和 pull 的先后顺序问题 最近提交代码,发现一个问题. 自己很清楚的记得本次的提交是没有进行合并的. 奇怪的死 gitlab中的 history 历史中显示了我对本次进行了Merge ...
- Ant Design Vue 单文件上传Upload
单文件上传 <a-upload name="file" :beforeUpload="beforeUpload" :multiple="fals ...
- 发布.net core应用程序并部署到IIS上
一.在项目里右击选择发布点击启动配置如下图所示 二.在打开的发布选项选择 配置 Release或DeBug ,目标框架选择对应的.net Core版本默认就行,部署模式有两种选择 1.框架依赖---- ...