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

 

 

 

 

 

-

posted @ 2022-08-28 13:28  古墩古墩  Views(115)  Comments(0Edit  收藏  举报