详解三种方式在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 相关文章推荐
javascript实现轮显新闻标题链接
Aug 13 Javascript
Jquery.LazyLoad.js修正版下载,实现图片延迟加载插件
Mar 12 Javascript
JavaScript 代码压缩工具小结
Feb 27 Javascript
Javascript堆排序算法详解
Dec 03 Javascript
基于jQuery1.9版本如何判断浏览器版本类型
Jan 12 Javascript
Angular2学习教程之组件中的DOM操作详解
May 28 Javascript
Bootstrap datepicker日期选择器插件使用详解
Jul 26 Javascript
js 只比较时间大小的实例
Oct 26 Javascript
微信小程序解除10个请求并发限制
Dec 18 Javascript
基于js实现复制内容到操作系统粘贴板过程解析
Oct 11 Javascript
JavaScript如何处理移动端拍摄图片旋转问题
Nov 16 Javascript
JavaScript实现滚动加载更多
Dec 27 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+javascript模拟Matrix画面
2006/10/09 PHP
用mysql_fetch_array()获取当前行数据的方法详解
2013/06/05 PHP
php批量上传的实现代码
2013/06/09 PHP
php结合mysql与mysqli扩展处理事务的方法
2016/06/29 PHP
laravel5.6 框架邮件队列database驱动简单demo示例
2020/01/26 PHP
jquery HotKeys轻松搞定键盘事件代码
2008/08/30 Javascript
JQUERY 浏览器判断实现函数
2009/08/20 Javascript
jquery.boxy插件的iframe扩展代码
2010/07/02 Javascript
基于jquery的跟随屏幕滚动代码
2012/07/24 Javascript
jquery parent和parents的区别分析
2013/10/02 Javascript
jQuery实现动态添加、删除按钮及input输入框的方法
2017/04/27 jQuery
Node.js创建Web、TCP服务器
2017/12/05 Javascript
Angular 组件之间的交互的示例代码
2018/03/24 Javascript
详解微信小程序-获取用户session_key,openid,unionid - 后端为nodejs
2019/04/29 NodeJs
vue实现在线翻译功能
2019/09/27 Javascript
[02:38]DOTA2英雄基础教程 噬魂鬼
2014/01/03 DOTA
基于python yield机制的异步操作同步化编程模型
2016/03/18 Python
python3操作mysql数据库的方法
2017/06/23 Python
Django 忘记管理员或忘记管理员密码 重设登录密码的方法
2018/05/30 Python
Python实现ping指定IP的示例
2018/06/04 Python
Python封装原理与实现方法详解
2018/08/28 Python
Python基础之文件读取的讲解
2019/02/16 Python
Python中正反斜杠(‘/’和‘\’)的意义与用法
2019/08/12 Python
python/golang 删除链表中的元素
2020/09/14 Python
Otticanet意大利:最顶尖的世界名牌眼镜, 能得到打折季的价格
2019/03/10 全球购物
标记环网Toke Ring IEEE802.5
2014/05/26 面试题
Java程序员常见面试题
2015/07/16 面试题
大学校庆邀请函
2014/01/11 职场文书
幼儿园消防演练方案
2014/02/13 职场文书
模具专业毕业推荐信
2014/03/08 职场文书
春节联欢晚会主持词范文
2014/03/24 职场文书
项目经理聘任书
2014/03/29 职场文书
研讨会主持词
2014/04/02 职场文书
大学毕业生推荐信
2014/07/09 职场文书
2015年商场工作总结
2015/04/27 职场文书
python状态机transitions库详解
2021/06/02 Python