React.js - доступ к компонентным методам
Почему я не могу получить доступ к методам компонента извне в 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);
6 ответов
React предоставляет интерфейс для того, что вы пытаетесь сделать через ref
атрибут Назначить компонент ref
обратный вызов, и он будет вызываться со ссылкой на компонент при его визуализации:
var Parent = React.createClass({
componentDidMount: function() {
console.log(this._child.someMethod()); // Prints 'bar'
},
render: function() {
return (
<div>
<Child ref={(child) => { this._child = child; }} />
</div>
);
}
});
Обновление 2016-09-19: изменен пример использования обратного вызова ref вместо строки ref в соответствии с указаниями ref
Строка атрибутов документов.
Примечание. Это будет работать только в том случае, если дочерний компонент объявлен как класс, согласно документации, найденной здесь: https://facebook.github.io/react/docs/refs-and-the-dom.html
Если вы хотите вызывать функции для компонентов извне React, вы можете вызывать их по возвращаемому значению renderComponent:
var Child = React.createClass({…});
var myChild = React.renderComponent(Child);
myChild.someMethod();
Единственный способ получить дескриптор экземпляра React Component вне React - сохранить возвращаемое значение React.renderComponent. Источник
В качестве альтернативы, если метод на Child действительно статичен (не является продуктом текущего реквизита, состояние), вы можете определить его на statics
и затем получить к нему доступ, как и к статическому методу класса. Например:
var Child = React.createClass({
statics: {
someMethod: function() {
return 'bar';
}
},
// ...
});
console.log(Child.someMethod()) // bar
По Реакту 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)
Начиная с 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();
Еще один простой способ:
функция снаружи:
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);
}
}
Пожалуйста, посмотрите полное руководство здесь: Как использовать "this" компонента React извне?