在事件处理程序中获取对 React 组件的引用
Get reference to React component in event handler
我可以将事件处理程序附加到 React 组件。有没有办法在事件处理程序中获取对该组件的引用?
var Foobar = React.createClass({
action: function () {
// ...
},
render: function () {
var child = React.Children.only(this.props.children),
props = _.omit(this.props, 'children');
return React.addons.cloneWithProps(child, props);
}
});
var App = React.createClass({
handleMouseEnter: function (event) {
// How to get reference to Foobar without using this.refs['foo']?
// I need to call *action* on it.
},
render: function () {
return (
<div>
<Foobar ref="foo" onMouseEnter={this.handleMouseEnter}>
...
</Foobar>
</div>
);
}
});
handleMouseEnter
在您提供的示例中(以及关于 onClick 将是传递给 Foobar 的处理程序的说明)默认情况下由 React 自动绑定到 App
实例的上下文案例。
考虑到这一点,this.refs.foo
或 this.refs['foo']
在您描述的上下文中应该可以正常工作,并且是正确的方法。
假设没有令人信服的理由将处理程序保留在 App 中,一个更干净的解决方案是将处理程序完全包含在 Foobar 中,如下所示:
var Foobar = React.createClass({
action: function () {
// ...
},
render: function () {
var child = React.Children.only(this.props.children),
props = _.omit(this.props, 'children');
return (
<div onClick={this.action} onMouseEnter={this.action}>
React.addons.cloneWithProps(child, props);
</div>
);
}
});
var App = React.createClass({
render: function () {
return (
<Foobar />
);
}
});
您必须将处理程序传播到子组件的根元素,如下所示:
var Foobar = React.createClass({
action: function (e) {
this.props.onClick(this);
},
render: function () {
return <div onClick={this.action}>{this.props.children}</div>;
}
});
var App = React.createClass({
handleMouseEnter: function (foobar) {
console.log(foobar);
},
render: function () {
return (
<Foobar ref="foo" onClick={this.handleMouseEnter} />
);
}
});
我想我理解 vbarbarosh 提出的问题,或者至少我有一个类似的问题让我想到了这个 post。因此,如果这不能回答最初的问题,希望它能帮助到这里的其他人。
在我的例子中,我有一个带有 n 个 children 的 React 组件,用于定义 UI 操作的配置选项。每个 child 都有一个不同的 ref 来标识输入代表的配置选项,我希望能够直接访问 ref,这样我就可以调用在我的 child 组件上公开的方法。 (我可以公开数据属性并使用 jQuery 来提取,但这似乎有很多额外的问题和性能问题)
我的第一次尝试是这样的:
...
<Config ref="showDetails" onChange={this.handleChange} />
<Config ref="showAvatar" onChange={this.handleChange} />
...
理想情况下,我想将所有更改事件绑定到单个处理程序,然后从调度事件的目标中提取引用。不幸的是,调度的 SyntheticEvent
没有 提供了一种获取目标引用的方法,因此我无法直接调用 this.ref[name].methodIWantToCall()
.
我确实找到了 React 文档中的一篇文章,它引导我找到解决方案:
https://facebook.github.io/react/tips/communicate-between-components.html
我们可以做的是利用 JavaScript 绑定并传入额外的参数。
...
<Config ref="showDetails" onChange={this.handleChange.bind(this, 'showDetails')} />
...
现在在我的处理程序中我得到了附加数据并且可以访问我的引用:
handleChange: function(refName, event) {
this.refs[refName].myMethodIWantToCall()
}
诀窍在于绑定时,参数顺序发生了变化,第一个参数现在是传入的绑定值,事件现在是第二个参数。希望对您有所帮助!
如果您以编程方式添加处理程序,则只需在 addEventListener
.
处用另一个函数包装处理程序回调即可将组件作为参数传递
我有这个使用滚动事件的例子:
componentDidMount() {
document.getElementById('theElementId').addEventListener('scroll', (e) => {
this.handleScroll(e, this);
});
}
handleScroll(event, _self) {
// Now you can access to the element using the param _self
}
render() {
return (
<div id="theElementId"></div>
)
}
另一种选择是使用 bind 方法,它将更改 this
的值:
componentDidMount() {
document.getElementById('theElementId').addEventListener('scroll', this.handleScroll.bind(this));
}
handleScroll(event) {
// Now you can access to the element using the param this
}
看看你的 App 组件,你可以试试这个:
var App = React.createClass({
handleMouseEnter: function (event) {
// reference it by using: this.refs[event._targetInst._currentElement.ref]
// same result as calling: this.refs.foo
console.log(this.refs[event._targetInst._currentElement.ref])
},
render: function () {
return (
<div>
<Foobar ref="foo" onMouseEnter={this.handleMouseEnter}>
...
</Foobar>
</div>
);
}
});
希望这对您有所帮助。 :)
此外,我正在使用 writing/declaring React Components 的 ES6 方式,这也稍微改变了 "this" 的行为。不确定这是否也可能在这里发挥作用。
我可以将事件处理程序附加到 React 组件。有没有办法在事件处理程序中获取对该组件的引用?
var Foobar = React.createClass({
action: function () {
// ...
},
render: function () {
var child = React.Children.only(this.props.children),
props = _.omit(this.props, 'children');
return React.addons.cloneWithProps(child, props);
}
});
var App = React.createClass({
handleMouseEnter: function (event) {
// How to get reference to Foobar without using this.refs['foo']?
// I need to call *action* on it.
},
render: function () {
return (
<div>
<Foobar ref="foo" onMouseEnter={this.handleMouseEnter}>
...
</Foobar>
</div>
);
}
});
handleMouseEnter
在您提供的示例中(以及关于 onClick 将是传递给 Foobar 的处理程序的说明)默认情况下由 React 自动绑定到 App
实例的上下文案例。
考虑到这一点,this.refs.foo
或 this.refs['foo']
在您描述的上下文中应该可以正常工作,并且是正确的方法。
假设没有令人信服的理由将处理程序保留在 App 中,一个更干净的解决方案是将处理程序完全包含在 Foobar 中,如下所示:
var Foobar = React.createClass({
action: function () {
// ...
},
render: function () {
var child = React.Children.only(this.props.children),
props = _.omit(this.props, 'children');
return (
<div onClick={this.action} onMouseEnter={this.action}>
React.addons.cloneWithProps(child, props);
</div>
);
}
});
var App = React.createClass({
render: function () {
return (
<Foobar />
);
}
});
您必须将处理程序传播到子组件的根元素,如下所示:
var Foobar = React.createClass({
action: function (e) {
this.props.onClick(this);
},
render: function () {
return <div onClick={this.action}>{this.props.children}</div>;
}
});
var App = React.createClass({
handleMouseEnter: function (foobar) {
console.log(foobar);
},
render: function () {
return (
<Foobar ref="foo" onClick={this.handleMouseEnter} />
);
}
});
我想我理解 vbarbarosh 提出的问题,或者至少我有一个类似的问题让我想到了这个 post。因此,如果这不能回答最初的问题,希望它能帮助到这里的其他人。
在我的例子中,我有一个带有 n 个 children 的 React 组件,用于定义 UI 操作的配置选项。每个 child 都有一个不同的 ref 来标识输入代表的配置选项,我希望能够直接访问 ref,这样我就可以调用在我的 child 组件上公开的方法。 (我可以公开数据属性并使用 jQuery 来提取,但这似乎有很多额外的问题和性能问题)
我的第一次尝试是这样的:
...
<Config ref="showDetails" onChange={this.handleChange} />
<Config ref="showAvatar" onChange={this.handleChange} />
...
理想情况下,我想将所有更改事件绑定到单个处理程序,然后从调度事件的目标中提取引用。不幸的是,调度的 SyntheticEvent
没有 提供了一种获取目标引用的方法,因此我无法直接调用 this.ref[name].methodIWantToCall()
.
我确实找到了 React 文档中的一篇文章,它引导我找到解决方案:
https://facebook.github.io/react/tips/communicate-between-components.html
我们可以做的是利用 JavaScript 绑定并传入额外的参数。
...
<Config ref="showDetails" onChange={this.handleChange.bind(this, 'showDetails')} />
...
现在在我的处理程序中我得到了附加数据并且可以访问我的引用:
handleChange: function(refName, event) {
this.refs[refName].myMethodIWantToCall()
}
诀窍在于绑定时,参数顺序发生了变化,第一个参数现在是传入的绑定值,事件现在是第二个参数。希望对您有所帮助!
如果您以编程方式添加处理程序,则只需在 addEventListener
.
我有这个使用滚动事件的例子:
componentDidMount() {
document.getElementById('theElementId').addEventListener('scroll', (e) => {
this.handleScroll(e, this);
});
}
handleScroll(event, _self) {
// Now you can access to the element using the param _self
}
render() {
return (
<div id="theElementId"></div>
)
}
另一种选择是使用 bind 方法,它将更改 this
的值:
componentDidMount() {
document.getElementById('theElementId').addEventListener('scroll', this.handleScroll.bind(this));
}
handleScroll(event) {
// Now you can access to the element using the param this
}
看看你的 App 组件,你可以试试这个:
var App = React.createClass({
handleMouseEnter: function (event) {
// reference it by using: this.refs[event._targetInst._currentElement.ref]
// same result as calling: this.refs.foo
console.log(this.refs[event._targetInst._currentElement.ref])
},
render: function () {
return (
<div>
<Foobar ref="foo" onMouseEnter={this.handleMouseEnter}>
...
</Foobar>
</div>
);
}
});
希望这对您有所帮助。 :) 此外,我正在使用 writing/declaring React Components 的 ES6 方式,这也稍微改变了 "this" 的行为。不确定这是否也可能在这里发挥作用。