React08-ref属性(二)与事件处理

86 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 8 天,点击查看活动详情

回调 ref 执行次数的问题

关于回调 ref 执行次数的问题,官网描述:

如果 ref 回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次,第一次传入参数 null,然后第二次会传入参数 DOM 元素。这是因为在每次渲染时会创建一个新的函数实例,所以 React 清空旧的 ref 并且设置新的。通过将 ref 的回调函数定义成 class 的绑定函数的方式可以避免上述问题,但是大多数情况下它是无关紧要的。

即内联函数形式,在更新过程中 ref 回调会被执行两次,第一次传入 null ,第二次传入 DOM 元素。若是下述形式,则只执行一次。但是对功能实现没有影响,因此一般也是用内联函数形式。

     <script type="text/babel">
         //创建组件
         class Demo extends React.Component{
 ​
             state = {isHot:false}
 ​
             showInfo = ()=>{
                 const {input1} = this
                 alert(input1.value)
             }
 ​
             changeWeather = ()=>{
                 //获取原来的状态
                 const {isHot} = this.state
                 //更新状态
                 this.setState({isHot:!isHot})
             }
 ​
             saveInput = (c)=>{
                 this.input1 = c;
                 console.log('@',c);
             }
 ​
             render(){
                 const {isHot} = this.state
                 return(
                     <div>
                         <h2>今天天气很{isHot ? '炎热':'凉爽'}</h2>
                         {/*<input ref={(c)=>{this.input1 = c;console.log('@',c);}} type="text"/><br/><br/>*/}
                         <input ref={this.saveInput} type="text"/><br/><br/>
                         <button onClick={this.showInfo}>点我提示输入的数据</button>
                         <button onClick={this.changeWeather}>点我切换天气</button>
                     </div>
                 )
             }
         }
         //渲染组件到页面
         ReactDOM.render(<Demo/>,document.getElementById('test'))
     </script>

createRef

React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点,该容器是“专人专用”的。一个容器只能存储一个节点。

     <script type="text/babel">
         //创建组件
         class Demo extends React.Component{
             /* 
                 React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点,该容器是“专人专用”的
              */
             myRef = React.createRef()
             myRef2 = React.createRef()
             //展示左侧输入框的数据
             showData = ()=>{
                 alert(this.myRef.current.value);
             }
             //展示右侧输入框的数据
             showData2 = ()=>{
                 alert(this.myRef2.current.value);
             }
             render(){
                 return(
                     <div>
                         <input ref={this.myRef} type="text" placeholder="点击按钮提示数据"/>&nbsp;
                         <button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
                         <input onBlur={this.showData2} ref={this.myRef2} type="text" placeholder="失去焦点提示数据"/>&nbsp;
                     </div>
                 )
             }
         }
         //渲染组件到页面
         ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))
     </script>

事件处理

  1. 通过onXxx属性指定事件处理函数(注意大小写)
  2. React使用的是自定义(合成)事件, 而不是使用的原生DOM事件
  3. React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)
  4. 通过event.target得到发生事件的DOM元素对象

!!:当触发事件的元素和需要操作的元素为同一个时,可以不使用 ref