IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> React系统学习4(組件三大核心属性之refs) -> 正文阅读

[JavaScript知识库]React系统学习4(組件三大核心属性之refs)

React三大核心属性state、props、refs,前边已经学过了state和props,现在开始最后一个refs的学习。

再从小需求说起

建立在业务基础上的技术才是最有价值的,假设有这样一个组件,一个输入框和一个按钮,需要在输入框中输入内容后,点击按钮则弹窗展示输入的内容。

需求比较简单,根据以往的经验,可能会写出这样的一段代码:

class Demo extends React.Component{

	showInput=()=>{
		alert(document.getElementById('input1').value)
	}

	render() {
		return (
			<div>
				<input id="input1" type="text" placeholder="点击按钮弹出输入内容"/>  
				<button onClick={this.showInput}>点击按钮弹出输入内容</button>  
			</div>
		)
	}
}

ReactDOM.render(<Demo />,document.getElementById('test'))

如果浏览器访问,会发现确实达到了想要的效果。

但是这里却有一个问题,那就是在React中除开特定的几个地方只能使用document.getElementById这种直接操作真实DOM的情况外,大多数时候是不应该直接操作真实DOM的。

原因之前应该也提到过,React会管理一个虚拟DOM,然后会把虚拟DOM渲染成真实DOM,但是渲染过程中并不是每次都全部内容渲染,而是会根据一定的算法,最终尽可能少的生成新的真实DOM,从而提升效率。

在React中提供了一个属性refs,就可以解决上边的问题。

string类型的refs

refs的用法有好几种,最简单的就是string类型的,那么上边的代码就可以改成这样:

class Demo extends React.Component{

	showInput=()=>{
		alert(this.refs.input1.value)
	}
   
	render() {
		return (
			<div>
				<input ref="input1" type="text" placeholder="点击按钮弹出输入内容"/>  
				<button onClick={this.showInput}>点击按钮弹出输入内容</button>  
			</div>
		)
	}
}

ReactDOM.render(<Demo />,document.getElementById('test'))

和之前不同的就是两个地方,一个是把id="input1"换成了ref="input1",另一个就是把alert(document.getElementById('input1').value)改成了alert(this.refs.input1.value)

很显然,在这里就没有再直接操作真实DOM。

当然了,上边代码也可以使用解构写法优化自定义方法中的代码,例如:

showInput=()=>{
	let {input1} = this.refs;
	alert(input1.value)
}

string用法看起来很简单,但是官网最新的文档已经说这是过时用法了,存在一些问题,不建议再使用,建议用函数式和createRef方式,下边就看看函数式

函数类型的refs

函数式分为内联函数和外部引用函数,使用内联函数式写法,上边代码就可以进一步改成这样:

class Demo extends React.Component{

	showInput=()=>{
		alert(this.input1.value)
	}
   
	render() {
		return (
			<div>
				<input ref={(node)=>{this.input1=node}} type="text" placeholder="点击按钮弹出输入内容"/>  
				<button onClick={this.showInput}>点击按钮弹出输入内容</button>  
			</div>
		)
	}
}

ReactDOM.render(<Demo />,document.getElementById('test'))

而使用外部引用函数类型的refs,代码则可以改成这样:

class Demo extends React.Component{

	showInput=()=>{
		alert(this.input1.value)
	}

	bindRef=(node)=>{
		this.input1=node
	}
   
	render() {
		return (
			<div>
				<input ref={this.bindRef} type="text" placeholder="点击按钮弹出输入内容"/>  
				<button onClick={this.showInput}>点击按钮弹出输入内容</button>  
			</div>
		)
	}
}

ReactDOM.render(<Demo />,document.getElementById('test'))

上边两份代码的区别就在于,第一个直接在ref后边定义了一个匿名的函数,而第二个则是先声明了一个函数,然后再在ref后边进行引用。

这两种写法看起来第一种更加简洁,可能也是实际用的更多的。

但是实际上有一个小细节,那就是第一种写法在每次重新render渲染的时候都会加载两次这个函数,当然了,大多数时候可能也没有太大影响。

createRef类型的refs

实际上函数式应该是用的最多的了,因为createRef这种写法必须在外边先进行定义,如下边这样:

class Demo extends React.Component{

	showInput=()=>{
		alert(this.bindRef.current.value)
	}

	bindRef=React.createRef()
   
	render() {
		return (
			<div>
				<input ref={this.bindRef} type="text" placeholder="点击按钮弹出输入内容"/>  
				<button onClick={this.showInput}>点击按钮弹出输入内容</button>  
			</div>
		)
	}
}

ReactDOM.render(<Demo />,document.getElementById('test'))

可能有人会说,为什么不直接把React.createRef()放在ref后边呢?

因为实际上发现这样写的时候根本无效,至于为什么,暂时就不太清楚。

正是由于这个原因,相比内联函数的写法似乎就要复杂一些,所以可能大多数时候都选择内联函数的写法。

最后做一个总结,refs三种用法,看似最简单的可能会被弃用,最常用的应该是内联函数方式。

同时,官网说不要过度使用refs,否则也可能造成性能问题,也就是说实际开发时能不用它就不用,而是该用react中的其他一些方式。

因为从上边代码中也可以看出来,我们用refs就是为了拿到某个节点,然后得到数据。

实际上这种需求,如果事件发生的位置和数据节点就是一个,完全可以通过event.target方式处理。

如果是类似上边示例中事件发生位置和数据节点不同的情况,实际上也可以通过后续受控组件和非受控组件的内容进行处理。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-24 09:20:29  更:2022-04-24 09:23:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:07:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码