React - ref、回调 ref 回调执行次数的问题、createRef 函数、事件处理

一、ref

1、字符串形式的 ref
html 复制代码
<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>字符串形式的 ref</title>
    </head>

    <body>
        <div id="test"></div>
    </body>

    <script src="../js/react/react.development.js" type="text/javascript"></script>
    <script src="../js/react/react-dom.development.js" type="text/javascript"></script>
    <script src="../js/react/babel.min.js" type="text/javascript"></script>
    <script type="text/babel">
        class Demo extends React.Component {
            showData = () => {

                // 这里收集的是真实 DOM
                alert(this.refs.input1.value);
            };

            showData2 = () => {
                alert(this.refs.input2.value);
            };

            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>
                );
            }
        }

        ReactDOM.render(<Demo />, document.getElementById("test"));
    </script>
</html>
2、回调函数形式的 ref
html 复制代码
<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>回调函数形式的 ref</title>
    </head>

    <body>
        <div id="test"></div>
    </body>

    <script src="../js/react/react.development.js" type="text/javascript"></script>
    <script src="../js/react/react-dom.development.js" type="text/javascript"></script>
    <script src="../js/react/babel.min.js" type="text/javascript"></script>
    <script type="text/babel">
        class Demo extends React.Component {
            showData = () => {
                alert(this.input1.value);
            };

            showData2 = () => {
                alert(this.input2.value);
            };

            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="失去焦点提示数据" />
                    </div>
                );
            }
        }

        ReactDOM.render(<Demo />, document.getElementById("test"));
    </script>
</html>

二、回调 ref 回调执行次数的问题

1、基本介绍
  1. 每次渲染时,内联回调都会被重新创建,类方法回调则不会被重新创建

  2. 先调用旧的 ref 回调,传入 null(清理),再调用新的 ref 回调,传入当前的 DOM 元素

阶段 类方法回调 内联回调
挂载 传入 DOM(1 次) 传入 DOM(1 次)
更新 不执行 先 null 后 DOM(2 次)
卸载 传入 null(1 次) 传入 null(1 次)
2、演示
html 复制代码
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>回调 ref 回调执行次数的问题</title>
	</head>

	<body>
		<div id="test"></div>
	</body>

	<script src="../js/react/react.development.js" type="text/javascript"></script>
	<script src="../js/react/react-dom.development.js" type="text/javascript"></script>
	<script src="../js/react/babel.min.js" type="text/javascript"></script>
	<script type="text/babel">
		class Demo extends React.Component {
			state = {
				isHot: true,
			};

			changeWeather = () => {
				const { isHot } = this.state;
				this.setState({
					isHot: !isHot,
				});
			};

			showData = () => {
				alert(this.input1.value);
			};

			getInput2 = (currentNode) => {
				this.input2 = currentNode;
				console.log("#", currentNode);
			};

			showData2 = () => {
				alert(this.input2.value);
			};

			render() {
				const { isHot } = this.state;

				return (
					<div>
						<div>今天天气很{isHot ? "炎热" : "凉爽"}</div>
						<button onClick={this.changeWeather}>点我切换天气</button>
						<br />
						<input
							ref={(currentNode) => {
								this.input1 = currentNode;
								console.log("@", currentNode);
							}}
							type="text"
							placeholder="点击按钮提示数据"
						/>
						&nbsp;
						<button onClick={this.showData}>点击提示左侧的数据</button>&nbsp;
						<input ref={this.getInput2} onBlur={this.showData2} type="text" placeholder="失去焦点提示数据" />
					</div>
				);
			}
		}

		ReactDOM.render(<Demo />, document.getElementById("test"));
	</script>
</html>

三、createRef 函数

1、基本介绍
  • React 的 createRef 函数在调用后返回一个容器,该容器可以存储被 ref 所标识的节点
2、演示
html 复制代码
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>createRef()</title>
	</head>

	<body>
		<div id="test"></div>
	</body>

	<script src="../js/react/react.development.js" type="text/javascript"></script>
	<script src="../js/react/react-dom.development.js" type="text/javascript"></script>
	<script src="../js/react/babel.min.js" type="text/javascript"></script>
	<script type="text/babel">
		class Demo extends React.Component {
			input1 = React.createRef();
			input2 = React.createRef();

			showData = () => {
				console.log(this.input1);
				alert(this.input1.current.value);
			};

			showData2 = () => {
				console.log(this.input2);
				alert(this.input2.current.value);
			};

			render() {
				return (
					<div>
						<input ref={this.input1} type="text" placeholder="点击按钮提示数据" />
						&nbsp;
						<button onClick={this.showData}>点击提示左侧的数据</button>&nbsp;
						<input ref={this.input2} onBlur={this.showData2} type="text" placeholder="失去焦点提示数据" />
					</div>
				);
			}
		}

		ReactDOM.render(<Demo />, document.getElementById("test"));
	</script>
</html>

四、事件处理

1、基本介绍
  1. 通过 onXxx 属性指定事件处理函数

    1. 原生:onclick,React:onClick

    2. React 使用的是自定义(合成)事件,不是原生的 DOM 事件(为了更好的兼容性)

    3. React 中的事件是通过事件委托的方式处理的(委托给组件最外层的元素,为了高效)

    4. 可以通过 event.target 得到发生事件的原生 DOM 对象

  2. 发生事件的元素正好是要操作的元素,就可以省略 ref,不要过度使用 ref

2、演示
html 复制代码
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>事件处理</title>
	</head>

	<body>
		<div id="test"></div>
	</body>

	<script src="../js/react/react.development.js" type="text/javascript"></script>
	<script src="../js/react/react-dom.development.js" type="text/javascript"></script>
	<script src="../js/react/babel.min.js" type="text/javascript"></script>
	<script type="text/babel">
		class Demo extends React.Component {
			input1 = React.createRef();
			input2 = React.createRef();

			showData = () => {
				alert(this.input1.current.value);
			};

			showData2 = (event) => {
				alert(event.target.value);
			};

			render() {
				return (
					<div>
						<input ref={this.input1} type="text" placeholder="点击按钮提示数据" />
						&nbsp;
						<button onClick={this.showData}>点击提示左侧的数据</button>&nbsp;
						<input ref={this.input2} onBlur={this.showData2} type="text" placeholder="失去焦点提示数据" />
					</div>
				);
			}
		}

		ReactDOM.render(<Demo />, document.getElementById("test"));
	</script>
</html>
相关推荐
LIO3 分钟前
ESLint 极简指南:让代码既规范又一致
前端·eslint
明月_清风11 分钟前
前端工程化七连问:从紧急修复到版本控制,一文打通工程化任督二脉
前端·前端工程化
用户67570498850215 分钟前
不装插件不写代码!教你一招搞定网页长截图!清晰且高效!
前端·chrome
tjl521314_2119 分钟前
01C++ 分离编译与多文件编程
前端·c++·算法
sayamber22 分钟前
vLLM 容器化部署实战:如何在云服务器上跑起高并发大模型推理服务
前端
LIO22 分钟前
Pinia 极简指南:Vue 3 官方状态管理库
前端·vue.js
Wenzar_1 小时前
# D3.js实战进阶:从基础图表到交互式数据仪表盘的全流程构建在现代前端开发中,**数据可视化已成为提升用户体验的核心能力之一
java·javascript·python·信息可视化·ux
燐妤1 小时前
前端HTML编程2:深入学习表单与表格
前端·学习·html5
要不枉此行1 小时前
【Python 实战】一键爬取 HTML 文档并合并为完整 PDF
python·pdf·html
菜鸟小码1 小时前
MapReduce 编程模型详解:Mapper、Reducer、Driver 三大核心组件
大数据·javascript·mapreduce