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>
相关推荐
weixin199701080165 分钟前
《XMZ 商品详情页前端性能优化实战》
前端·性能优化
ThridTianFuStreet小貂蝉16 分钟前
面试题2、讲一讲JS运行机制、微任务、宏任务、事件循环
javascript
happymaker062635 分钟前
vue中对list的函数处理方式总结,以及常见功能的实现方法
javascript·vue.js·list
还是大剑师兰特36 分钟前
vueup/vue-quill 详细介绍(Vue3 富文本编辑器)
javascript·vue.js·ecmascript
蜡台1 小时前
Uniapp H5Builderx 预览Html 显示404问题解决
前端·uni-app
threelab1 小时前
引擎案例分析 02|GeoLayer 大厂地理可视化方案深度拆解
javascript·3d·webgl
We་ct1 小时前
LeetCode 190. 颠倒二进制位:两种解法详解
前端·算法·leetcode·typescript
踩着两条虫1 小时前
AI驱动的Vue3应用开发平台深入探究(二十五):API与参考之Renderer API 参考
前端·javascript·vue.js·人工智能·低代码·前端框架·ai编程
信创DevOps先锋1 小时前
本土化突围:Gitee如何重新定义企业级项目管理工具价值
前端·gitee·jquery