React组件中的this的具体使用


Posted in Javascript onFebruary 28, 2018

React组件的this是什么

通过编写一个简单组件,并渲染出来,分别打印出自定义函数和render中的this:

import React from 'react';

const STR = '被调用,this指向:';

class App extends React.Component{
  constructor(){
    super()
  }

  //测试函数
  handler() {
    console.log(`handler ${STR}`,this);
  }

  render(){

    console.log(`render ${STR}`,this);
    return(
      <div>
        <h1>hello World</h1>
        <label htmlFor = 'btn'>单击打印函数handler中this的指向</label>
        <input id = "btn" type="button" value = '单击' onClick = {this.handler}/>
      </div>    
    )
  }
}
export default App

结果如图:

React组件中的this的具体使用

可以看到,render函数中的this指向了组件实例,而handler()函数中的this则为undefined,这是为何?

JavaScript函数中的this

我们都知道JavaScript函数中的this不是在函数声明的时候定义的,而是在函数调用(即运行)的时候定义的

var student = {
  func: function() {
    console.log(this);
  };
};

student.func();
var studentFunc = student.func;
studentFunc();

这段代码运行,可以看到student.func()打印了student对象,因为此时this指向student对象;而studentFunc()打印了window,因为此时由window调用的,this指向window。

这段代码形象的验证了,JavaScript函数中的this不是在函数声明的时候,而是在函数运行的时候定义的;

同样,React组件也遵循JavaScript的这种特性,所以组件方法的‘调用者'不同会导致this的不同(这里的 “调用者” 指的是函数执行时的当前对象)

“调用者”不同导致this不同

测试:分别在组件自带的生命周期函数以及自定义函数中打印this,并在render()方法中分别使用this.handler(),window.handler(),onCilck={this.handler}这三种方法调用handler():

/App.jsx
//测试函数
  handler() {
    console.log(`handler ${STR}`,this);
  }

  render(){
    console.log(`render ${STR}`,this);

    this.handler();
    window.handler = this.handler;
    window.handler();

    return(

      <div>
        <h1>hello World</h1>
        <label htmlFor = 'btn'>单击打印函数handler中this的指向</label>
        <input id = "btn" type="button" value = '单击' onClick = {this.handler}/>
      </div>    
    )
  }
}
export default App

React组件中的this的具体使用

可以看到:

  1. render中this -> 组件实例App对象;
  2. render中this.handler() -> 组件实例App对象 ;
  3. render中window.handler() -> window对象;
  4. onClick ={this.handler} -> undefined

继续使用事件触发组件的装载、更新和卸载过程:

/index.js
import React from 'react'
import {render,unmountComponentAtNode} from 'react-dom'

import App from './App.jsx'


const root=document.getElementById('root')

console.log("首次挂载");
let instance = render(<App />,root);

window.renderComponent = () => {
  console.log("挂载");
  instance = render(<App />,root);
}

window.setState = () => {
  console.log("更新");
  instance.setState({foo: 'bar'});
}


window.unmountComponentAtNode = () => {
  console.log('卸载');
  unmountComponentAtNode(root);
}

使用三个按钮触发组件的装载、更新和卸载过程:

/index.html
<!DOCTYPE html>
<html>
<head>
  <title>react-this</title>
</head>
<body>
  <button onclick="window.renderComponent()">挂载</button>
  <button onclick="window.setState()">更新</button>
  <button onclick="window.unmountComponentAtNode()">卸载</button>
  <div id="root">
    <!-- app -->
  </div>
</body>
</html>

运行程序,依次单击“挂载”,绑定onClick={this.handler}“单击”按钮,“更新”和“卸载”按钮结果如下:

React组件中的this的具体使用

1. render()以及componentDIdMount()、componentDIdUpdate()等其他生命周期函数中的this都是组件实例;

2. this.handler()的调用者,为render()中的this,所以打印组件实例;

3. window.handler()的“调用者”,为window,所以打印window;

4. onClick={this.handler}的“调用者”为事件绑定,来源多样,这里打印undefined。

-面对如此混乱的场景,如果我们想在onClick中调用自定义的组件方法,并在该方法中获取组将实例,我们就得进行转换上下文即绑定上下文:

自动绑定和手动绑定

  1. React.createClass有一个内置的魔法,可以自动绑定所用的方法,使得其this指向组件的实例化对象,但是其他JavaScript类并没有这种特性;
  2. 所以React团队决定不再React组件类中实现自动绑定,把上下文转换的自由权交给开发者;
  3. 所以我们通常在构造函数中绑定方法的this指向:
import React from 'react';
const STR = '被调用,this指向:';
class App extends React.Component{
  constructor(){
    super();
    this.handler = this.handler.bind(this);
  }
//测试函数
  handler() {
    console.log(`handler ${STR}`,this);
  }

  render(){
    console.log(`render ${STR}`,this);
    this.handler();
    window.handler = this.handler;
    window.handler();

    return(
      <div>
        <h1>hello World</h1>
        <label htmlFor = 'btn'>单击打印函数handler中this的指向</label>
        <input id = "btn" type="button" value = '单击' onClick = {this.handler}/>
      </div>    
    )
  }
}
export default App

将this.handler()绑定为组件实例后,this.handler()中的this就指向组将实例,即onClick={this.handler}打印出来的为组件实例;

总结:

React组件生命周期函数中的this指向组件实例;

自定义组件方法的this会因调用者不同而不同;

为了在组件的自定义方法中获取组件实例,需要手动绑定this到组将实例。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
也说JavaScript中String类的replace函数
Sep 22 Javascript
使用js对select动态添加和删除OPTION示例代码
Aug 12 Javascript
BootStrap 智能表单实战系列(十)自动完成组件的支持
Jun 13 Javascript
详解js数组的完全随机排列算法
Dec 16 Javascript
React简单介绍
May 24 Javascript
关于 angularJS的一些用法
Nov 29 Javascript
jQuery与vue实现拖动验证码功能
Jan 30 jQuery
浅谈vue-cli 3.0.x 初体验
Apr 11 Javascript
angularjs $http调用接口的方式详解
Aug 13 Javascript
用Cordova打包Vue项目的方法步骤
Feb 02 Javascript
Node.js + express实现上传大文件的方法分析【图片、文本文件】
Mar 14 Javascript
vue 组件中使用 transition 和 transition-group实现过渡动画
Jul 09 Javascript
浅谈Vue网络请求之interceptors实际应用
Feb 28 #Javascript
Node.js中DNS模块学习总结
Feb 28 #Javascript
Vue自定义指令实现checkbox全选功能的方法
Feb 28 #Javascript
如何在vue中使用ts的示例代码
Feb 28 #Javascript
angularjs select 赋值 ng-options配置方法
Feb 28 #Javascript
select获取下拉框的值 下拉框默认选中方法
Feb 28 #Javascript
AngularJS select加载数据选中默认值的方法
Feb 28 #Javascript
You might like
《被神捡到的男人》动画化计划进行中!
2020/03/06 日漫
解析php php_openssl.dll的作用
2013/07/01 PHP
PHP利用imagick生成组合缩略图
2016/02/19 PHP
PHP中危险的file_put_contents函数详解
2017/11/04 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
2017/11/14 PHP
juqery 学习之四 筛选过滤
2010/11/30 Javascript
js全选实现和判断是否有复选框选中的方法
2015/02/17 Javascript
面向切面编程(AOP)的理解
2015/05/01 Javascript
javascript 广告移动特效的实现代码
2016/06/25 Javascript
JS生成一维码(条形码)功能示例
2017/01/19 Javascript
js实现兼容PC端和移动端滑块拖动选择数字效果
2017/02/16 Javascript
Vue获取DOM元素样式和样式更改示例
2017/03/07 Javascript
js最简单的双向绑定实例讲解
2018/01/02 Javascript
解决vue页面DOM操作不生效的问题
2018/03/17 Javascript
webpack4 + react 搭建多页面应用示例
2018/08/03 Javascript
基于vue通用表单解决方案的思考与分析
2019/03/16 Javascript
VUE组件中的 Drawer 抽屉实现代码
2019/08/06 Javascript
vue中watch和computed的区别与使用方法
2020/08/23 Javascript
详解python3百度指数抓取实例
2016/12/12 Python
详解django三种文件下载方式
2018/04/06 Python
Flask模拟实现CSRF攻击的方法
2018/07/24 Python
Python并行分布式框架Celery详解
2018/10/15 Python
Python数据结构之栈、队列及二叉树定义与用法浅析
2018/12/27 Python
Python使用folium excel绘制point
2019/01/03 Python
python实现在cmd窗口显示彩色文字
2019/06/24 Python
Python 使用list和tuple+条件判断详解
2019/07/30 Python
Python数据可视化 pyecharts实现各种统计图表过程详解
2019/08/15 Python
python add_argument()用法解析
2020/01/29 Python
python代码xml转txt实例
2020/03/10 Python
html+js 实现markdown编辑器效果
2019/10/23 HTML / CSS
电气自动化大学生求职信
2013/10/16 职场文书
高中自我评价分享
2013/12/05 职场文书
毕业实习个人鉴定范文
2013/12/10 职场文书
大学生职业生涯规划书模板
2014/01/03 职场文书
初中生庆国庆演讲稿范文2014
2014/09/25 职场文书
回复函格式及范文
2015/07/14 职场文书