react组件三大核心属性之一refs;react中的事件处理
-
ref让react更容易获取dom,和id比较像。只要在dom上定义ref属性,就可以在组件实例的this.refs中获取到对应的dom元素。
字符串形式的refs
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>字符串形式的ref</title> </head> <body> <!-- 准备一个容器 --> <div id="test"></div> <!-- 引入react核心库 --> <script src="https://cdn.bootcdn.net/ajax/libs/react/18.2.0/umd/react.development.min.js"></script> <!-- 引入react-dom, 用于支持react操作dom, 需要在核心库之后引入 --> <script src="https://cdn.bootcdn.net/ajax/libs/react-dom/18.2.0/umd/react-dom.development.min.js"></script> <!-- 引入babel.js,用于将jsx转化为js --> <script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.18.7/babel.min.js"></script> <!-- 引入prop-types --> <script src="https://cdn.bootcdn.net/ajax/libs/prop-types/15.8.1/prop-types.min.js"></script> <script type="text/babel"> // 1.创建类组件 class Demo extends React.Component{ render() { return ( <div> <input ref="input1" type="text" placeholder="点击按钮提示数据" /> <button onClick={this.showData}>点我提示左侧的数据</button> <input ref="input2" onBlur={this.showData2 } type="text" placeholder="失去焦点提示数据" /> </div> ) } // 展示左侧输入框的数据 showData = () => { console.log(this); const { input1 } = this.refs; alert(input1.value) } // 展示右侧输入框内的数据 showData2 = () => { const { input2 } = this.refs; alert(input2.value) } } // 挂载 ReactDOM.render(<Demo />, document.getElementById('test')) </script> </body> </html>
字符串形式的ref已经不推荐使用,官方说效率不高
回调函数形式的ref(内敛回调、类绑定回调)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>回调函数形式的ref</title> </head> <body> <!-- 准备一个容器 --> <div id="test"></div> <!-- 引入react核心库 --> <script src="https://cdn.bootcdn.net/ajax/libs/react/18.2.0/umd/react.development.min.js"></script> <!-- 引入react-dom, 用于支持react操作dom, 需要在核心库之后引入 --> <script src="https://cdn.bootcdn.net/ajax/libs/react-dom/18.2.0/umd/react-dom.development.min.js"></script> <!-- 引入babel.js,用于将jsx转化为js --> <script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.18.7/babel.min.js"></script> <!-- 引入prop-types --> <script src="https://cdn.bootcdn.net/ajax/libs/prop-types/15.8.1/prop-types.min.js"></script> <script type="text/babel"> // 1.创建类组件 class Demo extends React.Component{ state = { isHot: true } render() { const { isHot } = this.state; return ( <div> { // ref内的回调函数的形参,就是ref所在的DOM节点;下面直接在实例上添加了属性,并把节点赋值给了这个属性 // 如果用内敛的回调函数 去接收dom节点,会有一个问题,在页面更新时,内敛的ref回调会执行两次,第一次是null、第二次才是dom节点(不过这种问题是无关紧要的) // 有一种方法可以避免 内敛回调函数更新时执行两次;把内敛回调函数改成class类绑定的回调函数; // ref内敛回调的多次调用问题既然无关紧要,可以直接写内敛回调,如果介意就写类绑定的回调函数 } <h1>{ isHot ? '炎热' : '凉爽'}</h1> {/*<input ref={ curretNode => { this.input1 = curretNode; console.log(curretNode, '@'); } } type="text" placeholder="点击按钮提示数据" />*/} <input ref={ this.saveInput } type="text" placeholder="点击按钮提示数据" /> <button onClick={this.showData}>点我提示左侧的数据</button> <input ref={ c => { this.input2 = c } } onBlur={this.showData2 } type="text" placeholder="失去焦点提示数据" /> <button onClick={this.changeWeather}>点我切换天气</button> </div> ) } // 切换天气 changeWeather = () => { const { isHot } = this.state; this.setState({ isHot: !isHot }) } // 这种类绑定的函数,再更新时不会频繁的调用,因为在更新时,react知道这个函数已经调用过了,而内敛回调函数,每次更新都会执行两次 saveInput = (currentNode) => { console.log(currentNode, 'currentNode'); this.input1 = currentNode; } // 展示左侧输入框的数据 showData = () => { alert(this.input1.value) } // 展示右侧输入框内的数据 showData2 = () => { alert(this.input2.value) } } // 挂载 ReactDOM.render(<Demo />, document.getElementById('test')) </script> </body> </html>
createRef
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>createRef</title> </head> <body> <!-- 准备一个容器 --> <div id="test"></div> <!-- 引入react核心库 --> <script src="https://cdn.bootcdn.net/ajax/libs/react/18.2.0/umd/react.development.min.js"></script> <!-- 引入react-dom, 用于支持react操作dom, 需要在核心库之后引入 --> <script src="https://cdn.bootcdn.net/ajax/libs/react-dom/18.2.0/umd/react-dom.development.min.js"></script> <!-- 引入babel.js,用于将jsx转化为js --> <script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.18.7/babel.min.js"></script> <!-- 引入prop-types --> <script src="https://cdn.bootcdn.net/ajax/libs/prop-types/15.8.1/prop-types.min.js"></script> <script type="text/babel"> // 1.创建类组件 class Demo extends React.Component{ /* React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点;(该容器是专人专用的) */ myRef = React.createRef(); // 一个createRef只能对应一个dom节点,如果复用,后面的会把前面的覆盖 render() { return ( <div> <input ref={this.myRef} type="text" placeholder="点击按钮提示数据" /> <button onClick={this.showData}>点我提示左侧的数据</button> </div> ) } // 展示左侧输入框的数据 showData = () => { console.log(this.myRef, 'this.myRef'); alert(this.myRef.current.value) } } // 挂载 ReactDOM.render(<Demo />, document.getElementById('test')) </script> </body> </html>
react中的事件处理
(1)通过onXxx属性指定事件处理函数(注意大小写) a.React使用的是自定义(合成)事件,而不是使用原生的DOM事件-----为了更好的兼容性 b.React中的事件是通过事件委托的方式处理的(委托给组件最外层的元素)------为了高效 (2)通过event.target得到发生事件的DOM元素对象------不要过度的使用ref
-