我想从React Element的实例调用React组件公开的方法。
例如,在这个jsfiddle https://jsfiddle.net/r6r8cp3z/中,我想从alertMessage
参考中调用HelloElement
方法。
有没有办法实现这一点,而无需编写额外的包装器?
编辑(从JSFiddle复制代码)
<div id="container"></div>
<button onclick="onButtonClick()">Click me!</button>
var onButtonClick = function () {
//call alertMessage method from the reference of a React Element! Something like HelloElement.alertMessage()
console.log("clicked!");
}
var Hello = React.createClass({displayName: 'Hello',
alertMessage: function() {
alert(this.props.name);
},
render: function() {
return React.createElement("div", null, "Hello ", this.props.name);
}
});
var HelloElement = React.createElement(Hello, {name: "World"});
React.render(
HelloElement,
document.getElementById('container')
);
有两种方法可以访问内部函数。一个是实例级,就像你想要的那样,是另一个静态级别。
您需要在React.render
返回时调用该函数。见下文。
看看ReactJS Statics。但请注意,静态函数无法访问实例级数据,因此this
将为undefined
。
var onButtonClick = function () {
//call alertMessage method from the reference of a React Element!
HelloRendered.alertMessage();
//call static alertMessage method from the reference of a React Class!
Hello.alertMessage();
console.log("clicked!");
}
var Hello = React.createClass({
displayName: 'Hello',
statics: {
alertMessage: function () {
alert('static message');
}
},
alertMessage: function () {
alert(this.props.name);
},
render: function () {
return React.createElement("div", null, "Hello ", this.props.name);
}
});
var HelloElement = React.createElement(Hello, {
name: "World"
});
var HelloRendered = React.render(HelloElement, document.getElementById('container'));
然后做HelloRendered.alertMessage()
。
我做过这样的事情:
class Cow extends React.Component {
constructor (props) {
super(props)
this.state = {text: 'hello'}
}
componentDidMount () {
if (this.props.onMounted) {
this.props.onMounted({
say: text => this.say(text)
})
}
}
render () {
return (
<pre>
___________________
< {this.state.text} >
-------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
</pre>
)
}
say (text) {
this.setState({text: text})
}
}
然后在其他地方:
class Pasture extends React.Component {
render () {
return (
<div>
<Cow onMounted={callbacks => this.cowMounted(callbacks)} />
<button onClick={() => this.changeCow()} />
</div>
)
}
cowMounted (callbacks) {
this.cowCallbacks = callbacks
}
changeCow () {
this.cowCallbacks.say('moo')
}
}
我没有测试过这个确切的代码,但是这与我在我的项目中所做的一致,并且它工作得很好:)。当然这是一个不好的例子,你应该只使用道具,但在我的情况下,子组件做了一个API调用,我想保留在该组件内。在这种情况下,这是一个很好的解决方案。
你可以这样做
import React from 'react';
class Header extends React.Component{
constructor(){
super();
window.helloComponent = this;
}
alertMessage(){
console.log("Called from outside");
}
render(){
return (
<AppBar style={{background:'#000'}}>
Hello
</AppBar>
)
}
}
export default Header;
现在,从这个组件的外部,你可以这样调用如下
window.helloComponent.alertMessage();
使用render
方法可能会弃用返回值,建议的方法是将回调引用附加到根元素。像这样:
ReactDOM.render( <Hello name="World" ref={(element) => {window.helloComponent = element}}/>, document.getElementById('container'));
然后我们可以使用window.helloComponent访问它,并且可以使用window.helloComponent.METHOD访问它的任何方法。
这是一个完整的例子:
var onButtonClick = function() {
window.helloComponent.alertMessage();
}
class Hello extends React.Component {
alertMessage() {
alert(this.props.name);
}
render() {
return React.createElement("div", null, "Hello ", this.props.name);
}
};
ReactDOM.render( <Hello name="World" ref={(element) => {window.helloComponent = element}}/>, document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>
<button onclick="onButtonClick()">Click me!</button>
您可以使用函数将onClick
处理程序添加到div(onClick
是React自己的onClick
实现),您可以在{ }
花括号内访问该属性,并显示警告消息。
如果您希望定义可以在组件类上调用的静态方法 - 您应该使用静态。虽然:
“在此块中定义的方法是静态的,这意味着您可以在创建任何组件实例之前运行它们,并且这些方法无法访问组件的道具或状态。如果要在静态中检查props的值方法,让调用者传入props作为静态方法的参数。“ (source)
一些示例代码:
const Hello = React.createClass({
/*
The statics object allows you to define static methods that can be called on the component class. For example:
*/
statics: {
customMethod: function(foo) {
return foo === 'bar';
}
},
alertMessage: function() {
alert(this.props.name);
},
render: function () {
return (
<div onClick={this.alertMessage}>
Hello {this.props.name}
</div>
);
}
});
React.render(<Hello name={'aworld'} />, document.body);
希望这对你有所帮助,因为我不知道我是否理解你的问题,所以如果我解释错了就纠正我:)
似乎静态不推荐使用,而使用render
公开某些函数的其他方法似乎也很复杂。与此同时,this Stack Overflow answer about debugging React虽然看似hack-y,却为我做了这份工作。
如果您在ES6中,只需在您的示例中使用“static”关键字,例如:static alertMessage: function() {
...
},
希望可以帮助那里的任何人:)
class AppProvider extends Component {
constructor() {
super();
window.alertMessage = this.alertMessage.bind(this);
}
alertMessage() {
console.log('Hello World');
}
}
您可以使用window.alertMessage()
从窗口中调用此方法。