• 【06】基础知识:React组件实例三大核心属性 - ref


    一、 ref 了解

    理解

    组件内的标签可以定义 ref 属性来标识自己

    使用

    1、字符串形式的 ref

    定义:
    获取:this.refs.input
    
    • 1
    • 2

    2、回调形式的 ref

    定义: this.input = currentNode} />
    定义简写: this.input = c} />
    获取DOM元素:this.input
    
    • 1
    • 2
    • 3

    3、createRef创建 ref 容器

    创建容器:myRef = React.createRef() 
    绑定:
    获取:this.myRef.current
    
    • 1
    • 2
    • 3

    二、案例

    需求:自定义组件, 功能说明如下

    点击按钮,提示第一个输入框中的值

    当第2个输入框失去焦点时,提示这个输入框中的值

    1、字符串形式的 ref (过时,不推荐,存在一些效率问题)

    通过 ref 给标签打标识,通过组件实例的 refs 属性获取对应的 DOM 元素

    DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>1_字符串形式的reftitle>
    head>
    <body>
    	
    	<div id="test">div>
    
    	
    	<script type="text/javascript" src="../js/react.development.js">script>
    	
    	<script type="text/javascript" src="../js/react-dom.development.js">script>
    	
    	<script type="text/javascript" src="../js/babel.min.js">script>
    
    	<script type="text/babel">
    		class Demo extends React.Component {
    			render() {
    				return (
    					<div>
    						<input ref="input1" type="text" placeholder="点击按钮提示数据" />&nbsp;
    						<button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
    						<input ref="input2" onBlur={this.showData2} type="text" placeholder="失去焦点提示数据" />
    					</div>
    				)
    			}
    
    			// 展示左侧输入框的数据
    			showData = () => {
    				const { input1 } = this.refs
    				alert(input1.value)
    			}
    
    			// 展示右侧输入框数据
    			showData2 = () => {
    				alert(this.refs.input2.value)
    			}
    		}
    
    		ReactDOM.render(<Demo a="1" b="2" />, document.getElementById('test'))
    	script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    2、回调函数形式的ref

    拿到当前 ref 所在的节点,React 调用回调函数,传入节点,挂载在实例自身,赋值给 input1

    DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>2_回调函数形式的reftitle>
    head>
    <body>
    	
    	<div id="test">div>
    
    	
    	<script type="text/javascript" src="../js/react.development.js">script>
    	
    	<script type="text/javascript" src="../js/react-dom.development.js">script>
    	
    	<script type="text/javascript" src="../js/babel.min.js">script>
    
    	<script type="text/babel">
    		class Demo extends React.Component {
    			render() {
    				return (
    					<div>
    						<input ref={currentNode => this.input1 = currentNode} type="text" placeholder="点击按钮提示数据" />&nbsp;
    						<button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
    						<input ref={c => this.input2 = c} onBlur={this.showData2} type="text" placeholder="失去焦点提示数据" />&nbsp;
    					</div>
    				)
    			}
    
    			// 展示左侧输入框的数据
    			showData = () => {
    				const { input1 } = this
    				alert(input1.value)
    			}
    			// 展示右侧输入框的数据
    			showData2 = () => {
    				alert(this.input2.value)
    			}
    		}
    
    		ReactDOM.render(<Demo />, document.getElementById('test'))
    	script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    3、回调ref中回调执行次数的问题

    如果 ref 回调函数是以内联函数的方式定义的,在更新过程中它会执行两次,第一次传入参数null,然后第二次会传入参数 DOM 元素。

    这是因为在每次渲染是会创建一个新的函数实例,所以 React 清空旧的 ref 并且设置新的。

    通过将 ref 的回调函数定成 class 的绑定函数的方式可以避免上述问题,但大多数情况下它是无关紧要的。

    内联函数方式定义(推荐,写法简单):

    执行 1+n*2 次,初次渲染和更新时执行(第一次null,第二次DOM元素),不会产生什么问题。

    绑定函数形式:

    执行1次,初次渲染时执行。

    jsx 中写注释:{/* … */}

    DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>3_回调ref中回调执行次数的问题title>
    head>
    <body>
    	
    	<div id="test">div>
    
    	
    	<script type="text/javascript" src="../js/react.development.js">script>
    	
    	<script type="text/javascript" src="../js/react-dom.development.js">script>
    	
    	<script type="text/javascript" src="../js/babel.min.js">script>
    	
    	<script type="text/babel">
    		class Demo extends React.Component {
    			state = { isHot: false }
    			render() {
    				return (
    					<div>
    						{/*  { this.input = c; console.log('@', c) }} type="text" /> */}
    						<input ref={this.saveInput} type="text" />
    						<button onClick={this.showData}>点我提示内容</button><br />
    
    						<h2>今天天气很{this.state.isHot ? '炎热' : '凉爽'}</h2>
    						<button onClick={this.changeWeather}>点我切换天气</button>
    					</div>
    				)
    			}
    
    			showData = () => {
    				alert(this.input.value)
    			}
    
    			changeWeather = () => {
    				this.setState({
    					isHot: !this.state.isHot
    				})
    			}
    
    			saveInput = c => {
    				this.input = c
    				console.log('@', c) // 初次渲染时执行1次
    			}
    		}
    
    		ReactDOM.render(<Demo />, document.getElementById('test'))
    	script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    4、createRef的使用

    React.createRef 调用后可以返回一个容器,该容器可以存储被 ref 所标识的节点,该容器是【专人专用】的。

    DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>4_createRef的使用title>
    head>
    <body>
    	
    	<div id="test">div>
    
    	
    	<script type="text/javascript" src="../js/react.development.js">script>
    	
    	<script type="text/javascript" src="../js/react-dom.development.js">script>
    	
    	<script type="text/javascript" src="../js/babel.min.js">script>
    
    	<script type="text/babel">
    		class Demo extends React.Component {
    			myRef = React.createRef()
    			myRef2 = React.createRef()
    
    			showData = () => {
    				// console.log(this.myRef) // 通过current取DOM元素
    				alert(this.myRef.current.value)
    			}
    
    			showData2 = () => {
    				alert(this.myRef2.current.value)
    			}
    
    			render() {
    				return (
    					<div>
    						<input ref={this.myRef} type="text" placeholder="点击按钮提示数据" />&nbsp;
    						<button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
    						<input onBlur={this.showData2} ref={this.myRef2} type="text" placeholder="失去焦点提示数据" />&nbsp;
    					</div>
    				)
    			}
    		}
    
    		ReactDOM.render(<Demo />, document.getElementById('test'))
    	script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
  • 相关阅读:
    在Scrapy框架中使用隧道代理
    HTTP HTTPS SSL TLS
    lftp传输文件到指定服务器上
    服务监控(五)之Grafana 接入Prometheus 的数据实现服务监控
    OpenCV图像处理——卷积操作
    TensorFlow 的基本概念和使用场景
    python实现五子棋游戏(pygame版)(附零基础学习资料)
    网络安全笔记6——数字证书与公钥基础设施
    玩转全志F1C200s 烧录 flash 镜像
    在k8s集群中部署EdgeMesh
  • 原文地址:https://blog.csdn.net/weixin_45559449/article/details/133820108