javascript - props - React.js: acceso a métodos de componentes
redux (6)
¿Por qué no puedo acceder a los métodos de componentes desde "afuera" en ReactJS? ¿Por qué no es posible y hay alguna forma de resolverlo?
Considera el código:
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);
Alternativamente, si el método en Child es realmente estático (no es un producto de props actual, state) puede definirlo en statics
y luego acceder a él como lo haría con un método de clase estático. Por ejemplo:
var Child = React.createClass({
statics: {
someMethod: function() {
return ''bar'';
}
},
// ...
});
console.log(Child.someMethod()) // bar
Como se menciona en algunos de los comentarios, ReactDOM.render
ya no devuelve la instancia del componente. Puede pasar una devolución de llamada de ref
cuando se renderiza la raíz del componente para obtener la instancia, de esta forma:
// React code (jsx)
function MyWidget(el, refCb) {
ReactDOM.render(<MyComponent ref={refCb} />, el);
}
export default MyWidget;
y:
// vanilla javascript code
var global_widget_instance;
MyApp.MyWidget(document.getElementById(''my_container''), function(widget) {
global_widget_instance = widget;
});
global_widget_instance.myCoolMethod();
Desde React 0.12, la API se modificó ligeramente . El código válido para inicializar myChild sería el siguiente:
var Child = React.createClass({…});
var myChild = React.render(React.createElement(Child, {}), mountNode);
myChild.someMethod();
React proporciona una interfaz para lo que intenta hacer a través del atributo ref
. Asigna a un componente una devolución de llamada ref
, y se invocará con una referencia al componente cuando se represente:
var Parent = React.createClass({
componentDidMount: function() {
console.log(this._child.someMethod()); // Prints ''bar''
},
render: function() {
return (
<div>
<Child ref={(child) => { this._child = child; }} />
</div>
);
}
});
Actualización 2016-09-19: Se modificó el ejemplo para usar la devolución de llamada de ref en lugar de ref de cadena por orientación de los documentos de atributo de cadena de ref
.
Nota : Esto solo funcionará si el componente secundario se declara como una clase, según la documentación que se encuentra aquí: https://facebook.github.io/react/docs/refs-and-the-dom.html#adding-a-ref-to-a-class-component
Si desea llamar funciones en componentes desde fuera de React, puede llamarlos en el valor de retorno de renderComponent:
var Child = React.createClass({…});
var myChild = React.renderComponent(Child);
myChild.someMethod();
La única forma de obtener un control para una instancia de React Component fuera de React es almacenando el valor de retorno de React.renderComponent. Source
También podría hacerlo así, no estoy seguro de si es un buen plan: 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)
}
}