在 reactjs 组件中限定范围 'this'

Scoping 'this' within a reactjs component

在构建我的第一个 reactjs 组件时,我在尝试使用助手 (makeWorkSiteUrl) 时得到了熟悉的 "undefined is not a function",因为 this 范围已经从零件。

当然,我只是做了大多数 JS 开发人员会做的事情,并在调用函数来解决问题之前声明了 that=this

但是,我想到这可能是一个常见问题。所以可能有 'better' 或 'react' 方法来实现同样的事情。或者,这可能表明该组件设计不当。是否有一种首选或可用的样式或方法而不是 that=this 来访问内部组件 functions/properties?

"Undefined is not a function":

var WorkSiteQuickList = React.createClass({
    propTypes: {
        data: React.PropTypes.object.isRequired     
    },
    render() {
        var workSiteNodes = this.props.data.work_sites.map(function (worksite) {
            var linkUrl = this.makeWorkSiteUrl(worksite.id) //Fail  
            return (
                <WorkSiteQuickListItem workSiteName={worksite.name} linkUrl={linkUrl} />
            );
        });
        return (
                <div>    
                    {workSiteNodes}             
               </div>
        );
    },
    makeWorkSiteUrl(workSiteId) {
        return "/worksite/"+ workSiteId;
    }   
});

按预期工作:

var WorkSiteQuickList = React.createClass({
    propTypes: {
        data: React.PropTypes.object.isRequired     
    },
    render() {
        that = this;
        var workSiteNodes = this.props.data.work_sites.map(function (worksite) {
            var linkUrl = that.makeWorkSiteUrl(worksite.id) //OK  
            return (
                <WorkSiteQuickListItem workSiteName={worksite.name} linkUrl={linkUrl} />
            );
        });
        return (
                <div>    
                    {workSiteNodes}             
               </div>
        );
    },
    makeWorkSiteUrl(workSiteId) {
        return "/worksite/"+ workSiteId;
    }   
});

我确定这个问题会被关闭,但我宁愿问它也不愿错过 "framework" 的关键部分。

以下是处理 this 范围的一些常见模式:

  • 利用 es6 转译器(比如您当前使用的 JSX 转换器,或恰好支持 JSX 的 babeljs),使用作用域为外部上下文的箭头函数(又名 词法范围).

     this.props.data.work_sites.map( (worksite) => { .... return ... } )
    
  • 传入this作为Array#map

  • 的第二个参数
  • 链绑定到你传入的函数上 Array#map

    function() {}.bind(this)
    

更新:我最近在 => 遇到了很多麻烦,this[=46 的断点处暂停时解析为 window =] 开发工具 render() 方法中。本来以为是babeljs的bug。然而,事实证明这实际上是开发工具无法理解源地图实际上将 this 替换为 _this