更新(2015年9月1日):OP已经使这个问题成为一个移动的目标。又更新了。所以,我觉得有责任更新我的回复。
首先,回答你提供的例子:
是的,这是可能的。
你可以通过更新Child的onClick为this.props.onClick来解决这个问题。绑定(null,这):
var Child = React.createClass({
render: function () {
return <a onClick={this.props.onClick.bind(null, this)}>Click me</a>;
}
});
Parent中的事件处理程序可以像这样访问组件和事件:
onClick: function (component, event) {
// console.log(component, event);
},
JSBin快照
但这个问题本身具有误导性
父母已经知道孩子的道具。
这在所提供的示例中并不清楚,因为实际上没有提供任何道具。这个示例代码可能更好地支持所提出的问题:
var Child = React.createClass({
render: function () {
return <a onClick={this.props.onClick}> {this.props.text} </a>;
}
});
var Parent = React.createClass({
getInitialState: function () {
return { text: "Click here" };
},
onClick: function (event) {
// event.component.props ?why is this not available?
},
render: function() {
return <Child onClick={this.onClick} text={this.state.text} />;
}
});
在这个例子中,您已经知道Child的道具是什么,这一点变得更加清楚。
JSBin快照
如果真的是用孩子的道具……
如果它真的是关于使用一个孩子的道具,你可以完全避免与孩子的任何联系。
JSX有一个扩展属性API,我经常在Child等组件上使用。它获取所有的道具并将它们应用到一个组件上。孩子看起来是这样的:
var Child = React.createClass({
render: function () {
return <a {...this.props}> {this.props.text} </a>;
}
});
允许你直接在父对象中使用这些值:
var Parent = React.createClass({
getInitialState: function () {
return { text: "Click here" };
},
onClick: function (text) {
alert(text);
},
render: function() {
return <Child onClick={this.onClick.bind(null, this.state.text)} text={this.state.text} />;
}
});
JSBin快照
当您连接额外的子组件时,不需要额外的配置
var Parent = React.createClass({
getInitialState: function () {
return {
text: "Click here",
text2: "No, Click here",
};
},
onClick: function (text) {
alert(text);
},
render: function() {
return <div>
<Child onClick={this.onClick.bind(null, this.state.text)} text={this.state.text} />
<Child onClick={this.onClick.bind(null, this.state.text2)} text={this.state.text2} />
</div>;
}
});
JSBin快照
但我怀疑这不是你的实际用例。所以让我们进一步挖掘……
一个健壮的实际示例
所提供示例的一般性质很难讨论。我已经创建了一个组件来演示上面问题的实际用途,以非常react的方式实现:
DTServiceCalculator工作示例
DTServiceCalculator回购
这个组件是一个简单的服务计算器。您向它提供一个服务列表(包含名称和价格),它将计算所选价格的总和。
孩子们是幸福的无知
ServiceItem是本例中的子组件。它对外界没有太多看法。它需要一些道具,其中之一是单击时要调用的函数。
<div onClick={this.props.handleClick.bind(this.props.index)} /> . <div onClick={this.props.handleClick.bind(this.props.index)
它只使用所提供的索引[source]调用所提供的handleClick回调函数。
父母就是孩子
DTServicesCalculator是这个例子中的父组件。它也是一个孩子。让我们看。
DTServiceCalculator创建一个子组件(ServiceItems)列表,并为它们提供道具[source]。它是ServiceItem的父组件,但它是传递列表给它的组件的子组件。它不拥有数据。因此它再次将组件的处理委托给它的父组件源
< serserceitem chosen={\ id}索引价格={\价格}handleServiceItem} - >
handleServiceItem捕获从子对象传递的索引,并将其提供给父对象[source]
handleServiceClick (index) {
this.props.onSelect(index);
}
主人无所不知
“所有权”的概念在React中很重要。我建议在这里阅读更多相关内容。
在我所展示的示例中,我一直将事件的处理委托给组件树,直到我们到达拥有状态的组件。
当我们最终到达那里时,我们像这样处理状态选择/取消选择:
handleSelect (index) {
let services = […this.state.services];
services[index].chosen = (services[index].chosen) ? false : true;
this.setState({ services: services });
}
结论
试着让你最外层的组件尽可能不透明。努力确保它们对于父组件可能选择如何实现它们的偏好很少。
请注意谁拥有您正在操作的数据。在大多数情况下,您需要将事件处理委托给拥有该状态的组件。
旁白:Flux模式是减少应用中这种必要连接的好方法。