详解三种方式在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的防止大图片撑破页面的实现代码(立即缩放)
Oct 24 Javascript
基于jQuery的弹出框插件
Mar 18 Javascript
随鼠标上下滚动的jquery代码
Dec 05 Javascript
JavaScript数字和字符串转换示例
Mar 26 Javascript
JavaScript中神奇的call()方法
Mar 12 Javascript
jQuery实现复选框批量选择与反选的方法
Jun 17 Javascript
理解javascript函数式编程中的闭包(closure)
Mar 08 Javascript
jQ处理xml文件和xml字符串的方法(详解)
Nov 22 Javascript
ionic环境配置及问题详解
Jun 27 Javascript
AngularJs+Bootstrap实现漂亮的计算器
Aug 10 Javascript
react 创建单例组件的方法
Apr 26 Javascript
如何构建 vue-ssr 项目的方法步骤
Aug 04 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实现用于验证所有类型的信用卡类
2015/03/24 PHP
Laravel 5.3 学习笔记之 安装
2016/08/28 PHP
PHP实现基于栈的后缀表达式求值功能
2017/11/10 PHP
javascript 原型模式实现OOP的再研究
2009/04/09 Javascript
JS的replace方法介绍
2012/10/20 Javascript
javascript图片相似度算法实现 js实现直方图和向量算法
2014/01/14 Javascript
手机号码,密码正则验证
2014/09/04 Javascript
jQuery EasyUI datagrid实现本地分页的方法
2015/02/13 Javascript
jfinal与bootstrap的登录跳转实战演习
2015/09/22 Javascript
jQuery使用serialize()表单序列化时出现中文乱码问题的解决办法
2016/07/27 Javascript
Vuejs第六篇之Vuejs与form元素实例解析
2016/09/05 Javascript
Node.js环境下Koa2添加travis ci持续集成工具的方法
2017/06/19 Javascript
AngularJS中ng-class用法实例分析
2017/07/06 Javascript
三分钟学会用ES7中的Async/Await进行异步编程
2018/06/14 Javascript
vue实现动态添加数据滚动条自动滚动到底部的示例代码
2018/07/06 Javascript
KOA+egg.js集成kafka消息队列的示例
2018/11/09 Javascript
vue-cli3环境变量与分环境打包的方法示例
2019/02/18 Javascript
浅谈Vue的响应式原理
2019/05/30 Javascript
layui-table获得当前行的上/下一行数据的例子
2019/09/24 Javascript
node.js使用yargs处理命令行参数操作示例
2020/02/11 Javascript
JavaScript 类的封装操作示例详解
2020/05/16 Javascript
[04:03]辉夜杯主赛事 12月25日RECAP精彩回顾
2015/12/26 DOTA
[00:10]DOTA2全国高校联赛速递
2018/05/30 DOTA
Python找出9个连续的空闲端口
2016/02/01 Python
Python通过Django实现用户注册和邮箱验证功能代码
2017/12/11 Python
Python全局变量与局部变量区别及用法分析
2018/09/03 Python
对python多线程中Lock()与RLock()锁详解
2019/01/11 Python
预订全球最佳旅行体验:Viator
2018/03/30 全球购物
请解释流与文件有什么不同
2016/07/29 面试题
护士自荐信怎么写
2013/10/18 职场文书
继承公证书
2014/04/09 职场文书
教室布置标语
2014/06/26 职场文书
北京导游词
2015/02/12 职场文书
义卖募捐活动总结
2015/05/09 职场文书
2015年学校图书室工作总结
2015/05/19 职场文书
MySQL高速缓存启动方法及参数详解(query_cache_size)
2021/07/01 MySQL