【问题标题】:React.js: onClick function from child to parentReact.js:从子到父的 onClick 函数
【发布时间】:2015-10-12 10:12:45
【问题描述】:

我以this 文章为例(React 方式),但它不适用于我。请指出我的错误,因为我不明白出了什么问题。

这是我看到的错误:

未捕获的类型错误:this.props.onClick 不是函数

这是我的代码:

// PARENT
var SendDocModal = React.createClass({
  getInitialState: function() {
    return {tagList: []};
  },
  render: function() {
    return (
      <div>
        {
          this.state.tagList.map(function(item) {
            return (
              <TagItem nameProp={item.Name} idProp={item.Id} onClick={this.HandleRemove}/>
            )
          })
        }
      </div>
    )
  },
  HandleRemove: function(c) {
    console.log('On REMOVE = ', c);
  }
});

// CHILD
var TagItem = React.createClass({
  render: function() {
    return (
      <span className="react-tagsinput-tag">
        <span>{this.props.nameProp}</span>
        <a className='react-tagsinput-remove' onClick={this.HandleRemove}></a>
      </span>
    )
  },
  HandleRemove: function() {
    this.props.onClick(this);
  }
});

提前致谢!

【问题讨论】:

  • 究竟是什么不工作?
  • 哎呀!对不起。我总是得到一个错误:未捕获的类型错误:this.props.onClick is not a function

标签: javascript onclick reactjs


【解决方案1】:

问题是map 回调中的this 没有引用React 组件,因此this.HandleRemoveundefined

您可以通过将第二个参数传递给map 来显式设置this 值:

this.state.tagList.map(function() {...}, this);

现在thisinside回调指的是与this相同的值outside回调,即SendDocModal实例。

这与 React 无关,它只是 JavaScript 的工作方式。有关更多信息和其他解决方案,请参阅 How to access the correct `this` context inside a callback?

【讨论】:

  • 嗨,菲利克斯。感谢您的回复。尝试不使用 for 循环(只是一个带有硬编码道具的组件),效果很好。但我不明白如何在我的情况下传递上下文。能否请您更详细地描述一下?
  • 抱歉,只是混淆了 forEach 和 map。这是相同的解决方案。查看我的答案中的链接以了解有关this 的更多信息。
  • 如果我理解正确,我应该这样做:code {this.state.tagList.map(function(item){ return( &lt;TagItem nameProp={item.Name} idProp={item.Id} contextProp={this} onClick={this.HandleRemove}/&gt; ) }, this)}, 但在这种情况下我得到相同的结果:Uncaught TypeError: this.props.contextProp.props.onClick is not a function
  • 不,只需在我的答案中实施解决方案即可。回调的主体保持不变。
  • 啊哈,现在我明白了。正确的代码是:code {this.state.tagList.map(function(item){ return( &lt;TagItem nameProp={item.Name} idProp={item.Id} onClick={this.HandleRemove}/&gt; ) }, this)}
【解决方案2】:

尝试以下方法:

    var SendDocModal = React.createClass({
        getInitialState: function() {

            var item = {};
            item.Name = 'First';
            item.Id = 123;

            var item2 = {};
            item2.Name = 'Second';
            item2.Id = 123456;
            return {tagList: [item,item2]};
        },

        HandleRemove: function(c){
            console.log('On REMOVE = ', c);
        },

        render: function() {
            return (<div>
                {this.state.tagList.map(function(item){
                    return(
                            <TagItem nameProp={item.Name} idProp={item.Id} key={item.Id} click={this.HandleRemove}/>
                    )}, this)}
                    </div>
            )       
        }

    });
    // CHILD
    var TagItem = React.createClass({

        handleClick: function(nameProp)
        {
            this.props.click(nameProp);
        },


        render: function(){
            return(
                <span className="react-tagsinput-tag" ><span onClick={this.handleClick.bind(this, this.props.nameProp)}>{this.props.nameProp}</span><a className='react-tagsinput-remove' ></a></span>
            )
        }
    }); 

变化不大:

在 tagList 映射后添加了“this”。老实说,我不完全确定为什么——也许更有经验的程序员可以告诉我们。

为每个 TagItem 添加了一个键。这是推荐的,控制台会通知你应该这样做,这样如果状态发生变化,React 可以相应地跟踪每个项目。

点击是通过道具传递的。见React js - having problems creating a todo list

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-27
  • 2021-07-23
  • 1970-01-01
  • 2019-06-19
  • 1970-01-01
相关资源
最近更新 更多