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>
相关推荐
Larcher4 小时前
React Router 不只是页面跳转:从 SPA 路由到权限守卫的完整实践
javascript·后端
Larcher4 小时前
大模型为什么每次回答都不一样?一文搞懂 Temperature、Top K 与 Top P
javascript·后端
用户938515635077 小时前
从零在浏览器里跑 DeepSeek-R1:WebGPU + Transformer.js 全链路实战
前端·设计模式·typescript
CodeSheep7 小时前
稚晖君公司人事大变动,来了!
前端·后端·程序员
鱼樱前端7 小时前
用 AI 做内容变收入
前端·人工智能·ai编程
eric-sjq8 小时前
10 分钟实战:用 0.6B 本地模型生成中文网页(WanlyFrontend + 编译器全流程)
javascript·机器学习·自然语言处理·html
浮生望8 小时前
React + TypeScript 组件设计进阶:从类型约束到无状态组件的三次进化
前端
To_OC8 小时前
LC 438 找到所有字母异位词:暴力超时后,我靠滑动窗口一招搞定
javascript·算法·leetcode
90后的晨仔8 小时前
Mac 开发 uni-app 终极方案:让安卓模拟器彻底脱离 Android Studio 独立运行
前端·vue.js
90后的晨仔8 小时前
别再搞混了!uni-app 中 node_modules 和 uni_modules 到底是什么关系?
前端