深入理解 React 中的上下文 this

写在前面

JavaScript中的作用域scope 和上下文 context 是这门语言的独到之处,每个函数有不同的变量上下文和作用域。这些概念是JavaScript中一些强大的设计模式的后盾。在ES5规范里,我们可以遵循一个原则——每个function内的上下文this指向该function的调用方。比如:

var Module = {    name: 'Jafeney',    first: function() {        console.log(this);   // this对象指向调用该方法的Module对象        var second = (function() {            console.log(this)  // 由于变量提升,this对象指向Window对象        })()    },    init: function() {        this.first()    }}Module.init()

超级产品经理:''}{item.title}]
})
}

_renderBody() {    let _renderRow = this.renderRow;    return this.state.dataSource.map((item) => {        return _renderRow && _renderRow(item)    })}render() {    let state = this.state;    return (                    {this._renderHead()}                    {this._renderBody()}    )}

}

export default Table

Component是React内的一个基类,用于继承和创建React自定义组件。ES6规范下的面向对象实现起来非常精简,class关键字 可以快速创建一个类,而Component类内的所有属性和方法均可以通过this访问。换而言之,在Component内的任意方法内,可以通过this.xxx的方式调用该Component的其他属性和方法。接着分析上面的代码,寥寥几行实现的是对一个Table组件的封装,借鉴了ReactNative组件的设计思路,通过外部传递dataSource(数据源)、columns(表格的表头项)、renderRow(当行渲染的模板函数)来完成一个Table的构建,支持全选和取消全选的功能、允许外部传递className和style对象来修改样式。从这个例子我们可以发现:只要不采用function定义函数,Component所有方法内部的this对象始终指向该类自身。### container 调用 component 时传递的 this还是继续上面的例子,下面在一个做为Demo的container里调用之前 的Table。

import Table from '../../components/Views/Table/'

接着编写renderRow函数并传递给Table组件

_renderRow(row) {
// ------------ 注意:这里对callback函数的写法 -----------
let onEdit = (x)=> {
console.log(x+x)
}, onDelete = (x)=> {
console.log(x*x)
}
// ---------------------------------------------------
return (

        {row.key}        {row.name}        {row.age}        {row.birthday}        {row.job}        {row.address}            onEdit(row.key)} text="编辑" />            onDelete(row.key)} text="删除" />)

}

//... 省略一大堆代码

render() {
let dataSource = [{
key: '1',
name: '胡彦斌',
age: 32,
birthday: '2016-12-29',
job: '前端工程师',
address: '西湖区湖底公园1号'
}, {
key: '2',
name: '胡彦祖',
age: 42,
birthday: '2016-12-29',
job: '前端工程师',
address: '西湖区湖底公园1号'
}],columns = [{
title: '编号',
dataIndex: 'key',
key: 'key',
},{
title: '姓名',
dataIndex: 'name',
key: 'name',
}, {
title: '年龄',
dataIndex: 'age',
key: 'age',
}, {
title: '生日',
dataIndex: 'birthday',
key: 'birthday',
}, {
title: '职务',
dataIndex: 'job',
key: 'job',
},{
title: '住址',
dataIndex: 'address',
key: 'address',
}, {
title: '操作',
dataIndex: 'operate',
key: 'operate',
}];
return (

);

}

显示效果如下:分析上面的代码,有几处容易出错的地方:1. _renderRow 作为component的方法来定义,然后在对应的render函数内通过this来调用。很重要的一点,这里this._renderRow作为的是函数名方式传递。1. _renderRow 内部Button组件的callback是按钮点击后触发的回调,也是一个函数,但是这个函数没有像上面一样放在component的方法里定义,而是作为一个变量定义并通过匿名函数的方式传递给子组件:

let onEdit = (x)=> {
console.log(x+x)
}

// .....
callback={()=>onEdit(row.key)}

这样就避开了使用this时上下文变化的问题。这一点是很讲究的,如果沿用上面的写法很容易这样写:

onEdit(x) {
console.log(x+x)
}

// ...
callback={()=>this.onEdit(row.key)}

但是很遗憾,这样写this传递到子组件后会变成undefined,从而报错。1. 父组件如要调用子组件的方法,有两种方式:第一种   通过匿名函数的方式

callback = {()=>this.modalShow()}

1. 第二种   使用 bind

callback = {this.modalShow.bind(this)}

注意:如果要绑定的函数需要传参数,可以这么写: xxx.bind(this,arg1,arg2...)## 参考《ECMAScript 6 入门》@欢迎关注我的 github 和 个人博客 -Jafeney#JavaScript、react.js、es2015#

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部