如何在ReactJS中从“外部”访问组件方法?

为什么我不能在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);
201338 次浏览

React为你试图通过ref属性来做的事情提供了一个接口。为一个组件分配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: 修改示例,使用ref回调每个指导从 ref String属性 docs。

或者,如果Child上的方法是真正静态的(不是当前props, state的产物),你可以在statics上定义它,然后像访问静态类方法一样访问它。例如:

var Child = React.createClass({
statics: {
someMethod: function() {
return 'bar';
}
},
// ...
});


console.log(Child.someMethod()) // bar

如果你想在React外部的组件上调用函数,你可以在renderComponent的返回值上调用它们:

var Child = React.createClass({…});
var myChild = React.renderComponent(Child);
myChild.someMethod();

在React外部获取React Component实例句柄的唯一方法是存储React. rendercomponent的返回值。

从React 0.12开始,API是轻微的改变。初始化myChild的有效代码如下:

var Child = React.createClass({…});
var myChild = React.render(React.createElement(Child, {}), mountNode);
myChild.someMethod();

可以也这样做,不确定这是否是一个好计划: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)
}
}

正如某些注释中提到的,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();

从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)

另一种方法很简单:

函数外:

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);
}
}

请在这里查看完整的教程:如何从外部使用React组件的“this”?