【问题标题】:ReactJS can't access "this" methodsReactJS 无法访问“this”方法
【发布时间】:2015-05-25 09:45:12
【问题描述】:

我正在尝试将方法传递给子组件以处理 onclick 事件。 我在网上看到了很多例子,但我无法让它工作。 当我在父级的渲染函数中并尝试将“this.handleClick”传递给子级时,handleClick 未定义。

看看 ThumbList 的 render 方法:

var Thumb = React.createClass({
        handleClick: function() {
            console.log(this)
            console.log('handleClick of Thumb')
            this.props.onClick()
        },
        render: function() {
            return(
                    <div className="thumb" key={this.props.thumb.url}>
                        <a href='#' onClick={this.handleClick}>
                            <img src={'/img/rings/thumbs/'+this.props.thumb.url+'_thumb.jpg'} alt="Image"> 
                            </img>         
                        </a>
                    </div>
                );
        }
    });

    var ThumbList = React.createClass({

        handleClick: function (id) {
            console.log('click of ThumbList');

        },


        loadFromServer: function() {
            $.ajax({
                url: 'rings/imgs/5',
                dataType: 'json',
                success: function(data) {
                    this.setState({data: data});
                }.bind(this),
                error: function(xhr, status, err) {
                    console.error('rings/imgs/5', status, err.toString());
                }.bind(this)
            });
        },
        getInitialState: function(){
            return {data: [] };
        },
        componentDidMount: function(){
              this.loadFromServer();
                setInterval(this.loadFromServer, 2000);
                },

        render: function() {
            var handlefunc=this.handleClick
            var thumbsNodes = this.state.data.map(function(thumb) {
                console.log(this.handleClick)  // is Undefined!
                console.log(handlefunc)   // is working
                return (
                        <Thumb thumb={thumb} key={thumb.url} onClick={handlefunc.bind(this,thumb.url)}/>
                );
            });

            return(
                        <div className="col-md-1 col-md-offset-1" id='thumbs'>
                            {thumbsNodes}
                        </div> 

                );
            }

    });

知道我可能缺少什么吗?

【问题讨论】:

标签: reactjs


【解决方案1】:

如果您在开发工作流程中使用像 Babel 这样的编译器,我建议您使用 arrow functions:

var thumbsNodes = this.state.data.map((thumb) => {
  console.log(this.handleClick);
  return <Thumb thumb={thumb} key={thumb.url} 
                onClick={this.handlefunc.bind(this,thumb.url)}/>;
});

如您所见,这是一个很好的紧凑语法。箭头函数将为您保留 this 上下文。 Babel 编译器生成使用闭包的 JavaScript:

var thumbsNodes = this.state.data.map(function(thumb) {
  var _this = this;
  console.log(_this.handleClick);
  return <Thumb thumb={thumb} key={thumb.url} 
                onClick={_this.handlefunc.bind(_this,thumb.url)}/>;
});

【讨论】:

    【解决方案2】:

    this 未定义,因为map 回调不知道它是什么。解决这个问题的最简单方法是传递第二个参数,它会在回调中将其用作this

    var thumbsNodes = this.state.data.map(function(thumb) {
      console.log(this.handleClick)
      return <Thumb thumb={thumb} key={thumb.url} onClick={handlefunc.bind(this,thumb.url)}/>
    }, this)
    

    更多:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

    【讨论】:

    • 谢谢!我没有意识到地图函数没有调用对象的“this”上下文。这解决了这个
    【解决方案3】:

    您需要获取对this 的引用,以便在您调用它时它是正确的上下文。

    试试

    render: function() 
    {
      var handlefunc = this.handleClick; // i assume this is just for debugging the issue
      var self = this;
      var thumbsNodes = this.state.data.map(function(thumb) 
      {
         console.log(self.handleClick)  // note the use of `self`
      });
    }
    

    【讨论】:

    • 另一个答案更简洁。使用技巧 self=this, that=this 有效,但有更优雅的解决方案
    • 这解决了你的问题,但是如果你想在其他地方重新使用回调,使用像这样的全局范围的变量并不是很有用。
    • @David 我同意,但是调用函数可以解决这个问题 - 例如,handleClick.call(self); 我也同意map 的范围参数是最好的方法,但考虑到我的问题假设对于海报,我建议的方法“更易读”。当范围界定不是很清楚时,到处都有this,这意味着不同的事情可能比我的例子中故意重新界定范围更令人困惑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-23
    • 2017-11-26
    • 2012-06-17
    • 2019-08-04
    相关资源
    最近更新 更多