详解三种方式在React中解决绑定this的作用域问题并传参


Posted in Javascript onAugust 18, 2020

在React中时常会遇到this指向的作用域问题 从而导致undefined报错

先来个Demo:
功能很简单 点击按钮改变文字

import React from 'react';

export default class BindWithThis extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      msg:"BindWithThis"
    }
  }

  render() { 
    return <div>
      <input type="button" value="Way1" onClick={this.changeMsg1}/>
      <hr/>
      <h3>{this.state.msg}</h3>
    </div>
  }

  changeMsg1(){
    console.log(this)
    this.setState({
      msg:"Way1"
    })
  }
}

但会遇到问题:Cannot read property ‘setState' of undefined

详解三种方式在React中解决绑定this的作用域问题并传参

这是因为 在changeMsg1方法内部的this指向的并不是外面的组件 因而根本就不会有setState()方法了 自然会报错

为此 有三种解决方法

方式一:在事件处理函数中使用.bind()

只要这样即可:

render() { 
    return <div>
      <input type="button" value="Way1" onClick={this.changeMsg1.bind(this)}/>
      <hr/>
      <h3>{this.state.msg}</h3>
    </div>
  }

bind()的作用是为前面的函数修改函数内部的this的指向 从而使得函数内部的this指向bind中的第一个参数

bind()还可以传值:
bind第一个参数后面的所有参数都会作为调用bind前面的函数的参数传递

render() { 
  return <div>
    <input type="button" value="Way1" onClick={this.changeMsg1.bind(this,"壹","贰")}/>
    <hr/>
    <h3>{this.state.msg}</h3>
  </div>
}

changeMsg1(arg1,arg2){
  this.setState({
    msg:"Way1"+arg1+arg2
  })
}

除了bind()之外 还有call()和apply() 它们都能改变函数内部的this的指向
不过bind()和call()/apply()的区别是:bind()并不会立即调用 而call()/apply()会立即调用

方式二:在构造函数中使用.bind()

当为一个函数调用bind 从而改变this的指向之后 bind函数的返回值是这个被改变this指向的函数的改变后的引用
bind并不会修改原函数的this的指向 而是返回一个修改后的函数的指向 因此需要重新接收方可生效

import React from 'react';

export default class BindWithThis extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      msg:"BindWithThis"
    }

    // 当为一个函数调用bind 改变this的指向之后 bind函数的返回值是这个被改变this指向的函数的改变后的引用 因此需要重新接收
    this.changeMsg2 = this.changeMsg2.bind(this,"壹","贰")
  }

  render() { 
    return <div>
      <input type="button" value="Way2" onClick={this.changeMsg2}/>
      <hr/>
      <h3>{this.state.msg}</h3>
    </div>
  }

  changeMsg2(arg1,arg2){
    this.setState({
      msg:"Way2"+arg1+arg2
    })
  }
}

方式三:使用箭头函数

利用了箭头函数的特性:箭头函数内部的this永远指向调用者方的this

render() { 
  return <div>
    <input type="button" value="Way3" onClick={() => {this.changeMsg3("壹","贰")}}/>
    <hr/>
    <h3>{this.state.msg}</h3>
  </div>
}

changeMsg3 = (arg1,arg2) => {
  this.setState({
    msg:"Way3"+arg1+arg2
  })
}

当然 更推荐使用更加方便的箭头函数

到此这篇关于详解三种方式在React中解决绑定this的作用域问题并传参的文章就介绍到这了,更多相关React绑定this作用域内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
jquery显示和隐藏div特效实例
Feb 27 Javascript
jQuery教程 $()包装函数来实现数组元素分页效果
Aug 13 Javascript
jQuery固定浮动侧边栏实现思路及代码
Sep 28 Javascript
Jquery基础教程之DOM操作
Aug 19 Javascript
JS简单模拟触发按钮点击功能的方法
Nov 30 Javascript
js简单实现图片延迟加载的方法
Jul 19 Javascript
javaScript语法总结
Nov 25 Javascript
用vue和node写的简易购物车实现
Apr 25 Javascript
微信小程序本地缓存数据增删改查实例详解
May 24 Javascript
基于vue-element组件实现音乐播放器功能
May 06 Javascript
Vue的click事件防抖和节流处理详解
Nov 13 Javascript
在Echarts图中给坐标轴加一个标识线markLine
Jul 20 Javascript
javascript实现移动端上传图片功能
Aug 18 #Javascript
八种Vue组件间通讯方式合集(推荐)
Aug 18 #Javascript
小程序实现上传视频功能
Aug 18 #Javascript
如何在selenium中使用js实现定位
Aug 18 #Javascript
vue实现移动端input上传视频、音频
Aug 18 #Javascript
React冒泡和阻止冒泡的应用详解
Aug 18 #Javascript
JavaScript数组排序的六种常见算法总结
Aug 18 #Javascript
You might like
PHP脚本数据库功能详解(下)
2006/10/09 PHP
PHP得到某段时间区间的时间戳 php定时任务
2012/04/12 PHP
浅析php与数据库代码开发规范
2013/08/08 PHP
php实现计数器方法小结
2015/01/05 PHP
基于GD2图形库的PHP生成图片缩略图类代码分享
2015/02/08 PHP
PHP比较运算符的详细介绍
2015/09/29 PHP
PHP浮点数的一个常见问题
2016/03/10 PHP
PHP简单日历实现方法
2016/07/20 PHP
JS获取月份最后天数、最大天数与某日周数的方法
2015/12/08 Javascript
JS定义类的六种方式详解
2016/05/12 Javascript
如何用JS判断两个数字的大小
2016/07/21 Javascript
js发送短信倒计时的简单实现方法
2016/09/08 Javascript
使用jquery如何获取时间
2016/10/13 Javascript
30分钟快速入门掌握ES6/ES2015的核心内容(上)
2018/04/18 Javascript
electron-vue利用webpack打包实现多页面的入口文件问题
2019/05/12 Javascript
vue实现计步器功能
2019/11/01 Javascript
如何优雅地取消 JavaScript 异步任务
2020/03/22 Javascript
再也不怕 JavaScript 报错了,怎么看怎么处理都在这儿
2020/12/09 Javascript
python和C语言混合编程实例
2014/06/04 Python
python MySQLdb使用教程详解
2018/03/20 Python
下载python中Crypto库报错:ModuleNotFoundError: No module named ‘Crypto’的解决
2018/04/23 Python
浅谈Series和DataFrame中的sort_index方法
2018/06/07 Python
在Python中通过getattr获取对象引用的方法
2019/01/21 Python
关于django 1.10 CSRF验证失败的解决方法
2019/08/31 Python
python多线程实现TCP服务端
2019/09/03 Python
Python2与Python3的区别详解
2020/02/09 Python
CSS3按钮鼠标悬浮实现光圈效果源码
2016/09/11 HTML / CSS
ivx平台开发之不用代码实现一个九宫格抽奖功能
2021/01/27 HTML / CSS
你对IPv6了解程度
2016/02/09 面试题
销售自我评价
2013/10/22 职场文书
女大学生自我鉴定
2013/12/09 职场文书
银行竞聘上岗演讲稿
2014/09/12 职场文书
2014年实习班主任工作总结
2014/11/08 职场文书
办公室卫生管理制度
2015/08/04 职场文书
解除合同协议书范本
2016/03/21 职场文书
教你怎么用Python生成九宫格照片
2021/05/20 Python