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>
相关推荐
TiDi2 小时前
吸顶导航交互实现
前端
kisshyshy2 小时前
从Props透传到自定义Hook:系统梳理React跨层级通信与逻辑复用
前端·架构·代码规范
yume_sibai2 小时前
05-Flutter实战项目
前端·flutter
涛涛ing3 小时前
React 19.3 发布,但真正的赢家是 StyleX:当 AI 成为框架的“第一用户”
前端
zhangminghuan3 小时前
Vue vs React 实战拓展面试题|摒弃基础八股,聚焦业务开发核心难点(2026前端进阶)
前端
IT_陈寒3 小时前
Redis主从切换竟让业务卡了3秒?这个坑我替你踩了
前端·人工智能·后端
天若有情6734 小时前
独立开发复盘:我用 Node.js 做了个在线工具箱
前端·json·工具
xieliyu.4 小时前
前端基础:常见CSS选择器用法
前端·css·笔记·vscode
zttbee4 小时前
前端测试内容
前端
2603_965896624 小时前
async/await|JS同步写法解决异步终极方案
前端·javascript