为什么我不能在ReactJS中从“外部”访问组件方法?为什么不可能,有没有办法解决它?
考虑代码:
var Parent = React.createClass({
render: function() {
var child = <Child />;
return (
<div>
{child.someMethod()} // expect "bar", got a "not a function" error.
</div>
);
}
});
var Child = React.createClass({
render: function() {
return (
<div>
foo
</div>
);
},
someMethod: function() {
return 'bar';
}
});
React.renderComponent(<Parent />, document.body);
答案 0 :(得分:167)
React通过ref
attribute为您尝试执行的操作提供了一个界面。为ref
分配一个组件,其current
属性将是您的自定义组件:
class Parent extends React.Class {
constructor(props) {
this._child = React.createRef();
}
componentDidMount() {
console.log(this._child.current.someMethod()); // Prints 'bar'
}
render() {
return (
<div>
<Child ref={this._child} />
</div>
);
}
}
注意:这仅在子组件声明为类时才有效,根据此处的文档:https://facebook.github.io/react/docs/refs-and-the-dom.html#adding-a-ref-to-a-class-component
更新2019-04-01: 更改了示例以使用类和createRef
每个最新的React文档。
更新2016-09-19: 更改了示例,以便根据the ref
String attribute文档的指南使用参考回调。
答案 1 :(得分:38)
如果要从React外部调用组件上的函数,可以在renderComponent的返回值上调用它们:
var Child = React.createClass({…});
var myChild = React.renderComponent(Child);
myChild.someMethod();
获取React之外的React Component实例句柄的唯一方法是存储React.renderComponent的返回值。 Source
答案 2 :(得分:36)
或者,如果Child上的方法是真正的静态(不是当前props,state的产品),您可以在statics
上定义它,然后像访问静态类方法一样访问它。例如:
var Child = React.createClass({
statics: {
someMethod: function() {
return 'bar';
}
},
// ...
});
console.log(Child.someMethod()) // bar
答案 3 :(得分:4)
自React 0.12起,API为slightly changed。初始化myChild的有效代码如下:
var Child = React.createClass({…});
var myChild = React.render(React.createElement(Child, {}), mountNode);
myChild.someMethod();
答案 4 :(得分:2)
从React 16.3起,可以使用React.createRef
((使用ref.current
进行访问)
var ref = React.createRef()
var parent = <div><Child ref={ref} /> <button onClick={e=>console.log(ref.current)}</div>
React.renderComponent(parent, document.body)
答案 5 :(得分:0)
你可以也这样做,不确定这是不是一个好计划:D
class Parent extends Component {
handleClick() {
if (this._getAlert !== null) {
this._getAlert()
}
}
render() {
return (
<div>
<Child>
{(getAlert, childScope) => (
<span> {!this._getAlert ? this._getAlert = getAlert.bind(childScope) : null}</span>
)}
</Child>
<button onClick={() => this.handleClick()}> Click me</button>
</div>
);
}
}
class Child extends Component {
constructor() {
super();
this.state = { count: 0 }
}
getAlert() {
alert(`Child function called state: ${this.state.count}`);
this.setState({ count: this.state.count + 1 });
}
render() {
return this.props.children(this.getAlert, this)
}
}
答案 6 :(得分:0)
正如一些评论中所提到的,ReactDOM.render
不再返回组件实例。您可以在渲染组件的根目录时传递ref
回调来获取实例,如下所示:
// React code (jsx)
function MyWidget(el, refCb) {
ReactDOM.render(<MyComponent ref={refCb} />, el);
}
export default MyWidget;
和
// vanilla javascript code
var global_widget_instance;
MyApp.MyWidget(document.getElementById('my_container'), function(widget) {
global_widget_instance = widget;
});
global_widget_instance.myCoolMethod();
答案 7 :(得分:-1)
另一种简单的方法:
外部功能:
function funx(functionEvents, params) {
console.log("events of funx function: ", functionEvents);
console.log("this of component: ", this);
console.log("params: ", params);
thisFunction.persist();
}
绑定它:
constructor(props) {
super(props);
this.state = {};
this.funxBinded = funx.bind(this);
}
}
请在此处查看完整的教程:How to use "this" of a React Component from outside?