• react中关于函数调用()与bind this的原因


    //函数组件则就是 无状态组件  只负责数据的展示(静态)
    //类组件这就是有状态组件      负责更新ui,让页面动起来
    //状态(state )就是数据,是组件内部的私有数据,只能在组件内部使用
    //state的值是对象,即就是一个组件内部可以拥有多个数据
    class StateComponent extends React.Component{
      //使用es6简化办法初始化
      state={
        count:0
      }
      addClick(){
        this.setState({count : this.state.count + 1});
      }
      addClick2=()=>{
        this.setState({count : this.state.count + 1});
      }
      render(){
        return(
          <>
        <button onClick={()=>{
          this.setState({
            count: this.state.count+1
          })
        }}>有状态组件,{this.state.count}</button>
    
        <button onClick={this.addClick.bind(this)} >bind使用</button>
        <button onClick={()=>this.addClick()} >箭头函数使用</button>
        </>
        )
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    由于初学js以及react框架,所以对于jsx插值表达式中的函数调用有些疑问

    function check(){
    }
    
    • 1
    • 2

    1、有些插值表达式调用函数不需要使用(),如{check};但是有些地方调用则需要使用(),如{check()}
    2、在使用react中的onClick函数时,调用函数如果函数内部没有使用this,则可以直接调用{check};如果使用了this则需要使用特殊处理,如最顶部的代码所示。

    答1:
    在界面直接使用jsx插值表达式,如果是希望直接返回函数结果,需要使用{check()};如果不需要直接调用函数,而是等待某些触发条件再调用函数{check}。这里函数的()即就是函数调用,而函数名是指向函数体的指针。

    react官网对于以下问题的解答可以很好地看出()的区别
    为什么我的函数每次组件渲染时都会被调用?
    确保你在传递一个函数给组件时,没有调用这个函数:

    hadleClick(){
     return <div>hello world</div>
     //函数体内部没有使用this
    }
    
    • 1
    • 2
    • 3
    • 4
    render() {
      // Wrong: handleClick is called instead of passed as a reference!
      return <button onClick={this.handleClick()}>Click Me</button>
    }
    
    • 1
    • 2
    • 3
    • 4

    正确做法是,传递函数本身(不带括号):

    render() {
      // Correct: handleClick is passed as a reference!
      return <button onClick={this.handleClick}>Click Me</button>
    }
    
    • 1
    • 2
    • 3
    • 4

    答2:
    js本身有一个特性,如果直接调用函数,尽管函数内部使用了this也可以正常使用。但是如果函数内容使用了this,但是不是直接调用这个函数,则内部的this会丢失,this会变成undefined。所以下面代码中renderList()直接调用,使用{this.renderList()},尽管函数体内部使用了this,也不需要特殊处理。但是onClick就不是直接调用。这里的onClick就相当于一个中间量。函数体内部的this指向会丢失。

    class Comment extends React.Component{
        state={
             comments:[
                {id:1,name:'jack',comment:"沙发"},
                {id:2,name:"tom",comment:'沙发不错'},
                {id:3,name:"blue",comment:"还行"}
             ]
        }
        renderList(){
            return(
                this.state.comments.kength===0?
                    <div className="no-comment" >暂无评论,快去评论</div>:
                    <ul >
                  {this.state.comments&&this.state.comments.map(comment=>
                      <li key={comment.id}><h3>评论人:{comment.name}</h3>
                      <p>评论内容 :{comment.content}</p>
                      </li>
                  )} 
                   </ul>
                  
            )
        }
          render(){
            return(
                <>
                {this.renderList()}
                 </>
            )
          }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    this的丢失可以使用箭头函数来解决,因为箭头函数具有如下特质:
    箭头函数的时候,箭头函数会默认帮我们绑定外层 this 的值,所以在箭头函数中 this 的值和外层的 this 是一样的。
    因此可以通过使用箭头函数避免this的丢失,当然为了避免this的丢失还有很多种方式
    1、使用es5的语法,在初始化component的时候使用constructor,对函数进行绑定
    2、在中间量声明时使用bind(this) 进行绑定
    3、中间量声明函数时使用箭头函数,可以直接进行函数调用,或者将函数内容直接书写在箭头函数内(注意这里进行函数调用时需要使用函数名+(),因为在函数内部声明是直接调用)
    4、最常用的方式,使用箭头函数声明函数,则可以直接调用,不需要额外处理

  • 相关阅读:
    微信小程序,连续播放多段视频。合成一个视频的样子,自定义视频进度条
    BS4网络提取selenium.chrome.WebDriver类的方法及属性
    Python反序列化免杀上线CS:两次编码绕过
    【红绿灯识别】红绿灯识别【含GUI Matlab源码 1908期】
    增强现实(AR)开发框架
    Android studio 一次编译生成32位和64位bin和lib
    前端js实现井字游戏和版本号对比js逻辑【适用于vue和react】
    WebDriverManager自动管理浏览器Driver包
    Go 基础语法 轻松上手 goland~
    全志A40i应用笔记 | 3种常见的网卡软件问题以及排查思路
  • 原文地址:https://blog.csdn.net/qq_44017078/article/details/125570697