12

我正在通过一个小例子来学习 Facebook React。我决定检查我对this绑定的了解是否正常,因此我创建了三个React.class可变状态位于父级的位置,中间仅将回调传递给子级以对其进行操作。

基本结构:

- MainFrame (states here)
  - FriendBox (only pass the callbacks for change states to Friend)
    -Friend

请注意,我无法使用transferThisProp,但实际上我更喜欢“手动”制作。

FriendBox 渲染包含以下内容:

var allFriends = this.props.friends.map((function (f) {
  return(
    <Friend key = {f.id}
            name = {f.name}
            select = {this.props.select}
    />
  )
}).bind(this))  

朋友渲染包含以下内容:

return(
  <div className="friend">
    {this.props.name}
    <a href="" onClick={this.props.select(this.props.key)}>
      select
    </a>
  </div>
)

运行我的代码时,我收到以下消息:

MainFrame.sendToFriendH:
  Invariant Violation: receiveComponent(...):
  Can only update a mounted component. react.js:7276
Uncaught Error: Invariant Violation:
  receiveComponent(...): Can only update a mounted component. 

有趣的是,当使用 chrome 的 react 扩展时,我可以检查虚拟DOM是否正常并且绑定是否正常。一切看起来都很好,除了第一个Friend元素的子组件说_lifeCycleState: "UNMOUNTED"

这让我觉得我犯了一个错误,底部的孩子没有被渲染和安装。所有代码都失败了,但我不知道确切原因。谁能告诉我为什么该元素没有自动安装,我该如何解决?

完整代码:http: //jsfiddle.net/RvjeQ/

4

2 回答 2

19

当你写

onClick={this.props.select(this.props.key)}

您正在this.props.select立即调用处理程序并将其结果设置为 onClick 处理程序。我猜你想改为做一个部分应用程序,你可以使用箭头函数来做:

onClick={(e) => this.props.select.bind(this.props.key, e)}

如果你不关心事件 arg,你可以跳过它。

你也可以.bind()像这样使用:

onClick={this.props.select.bind(null, this.props.key)}
于 2014-02-04T18:29:34.827 回答
3

为了它的价值,你不必做

this.props.friends.map((function(){ ... }).bind(this));

Array.prototype.map的第二个参数允许您设置回调函数的上下文。改用这个

this.props.friends.map(function(f){ ... }, this);

您还可以使用具有词法范围的箭头函数

this.props.friends.map(f =>
  <Friend key = {f.id}
          name = {f.name}
          select = {this.props.select}
  />
)

此外,当您使用复杂的道具时,您可以执行以下操作

var props = {
  key:    f.id,
  name:   f.name,
  select: this.props.select
};

<Friend {...props} />
于 2014-12-09T05:21:55.593 回答