Llamar a un método de componente React desde afuera

Quiero llamar a un método expuesto por un componente Reaccionar desde la instancia de un Elemento Reaccionado.

Por ejemplo, en este jsfiddle https://jsfiddle.net/r6r8cp3z/ Quiero llamar al método alertMessage de la referencia HelloElement .

¿Hay alguna forma de lograr esto sin tener que escribir envoltorios adicionales?

Editar (código copiado de JSFiddle)

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

Hay dos formas de acceder a una función interna. Uno, nivel de instancia, como quieras, otro, nivel estático.

Ejemplo

React.render llamar a la función en la statement de React.render . Vea abajo.

Estático

Echa un vistazo a ReactJS Statics . Sin embargo, tenga en cuenta que una función estática no puede acceder a los datos de nivel de instancia, por lo que undefined estaría 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')); 

A continuación, HelloRendered.alertMessage() .

He hecho algo como esto:

 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 ( 
 ___________________ < {this.state.text} > ------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || 

) } say (text) { this.setState({text: text}) } }

Y luego en otro lugar:

 class Pasture extends React.Component { render () { return ( 
) } cowMounted (callbacks) { this.cowCallbacks = callbacks } changeCow () { this.cowCallbacks.say('moo') } }

No he probado este código exacto, pero esto es lo que hice en un proyecto mío y funciona muy bien :). Por supuesto, este es un mal ejemplo, solo debes usar accesorios para esto, pero en mi caso el subcomponente hizo una llamada API que yo quería mantener dentro de ese componente. En tal caso, esta es una buena solución.

Puedes hacer como

 import React from 'react'; class Header extends React.Component{ constructor(){ super(); window.helloComponent = this; } alertMessage(){ console.log("Called from outside"); } render(){ return (  Hello  ) } } export default Header; 

Ahora, desde fuera de este componente, puede hacer una llamada como esta a continuación

 window.helloComponent.alertMessage(); 

Simplemente puede agregar un controlador onClick al div con la función ( onClick es la implementación propia de React de onClick ) y puede acceder a la propiedad dentro de { } llaves, y su mensaje de alerta aparecerá.

En caso de que desee definir métodos estáticos a los que pueda recurrirse en la clase de componente, debe usar estática. A pesar de que:

“Los métodos definidos en este bloque son estáticos, lo que significa que puede ejecutarlos antes de que se creen instancias de componentes, y los métodos no tienen acceso a los accesorios o al estado de los componentes. Si desea verificar el valor de los accesorios en un entorno estático método, haga que la persona que llama pase los accesorios como un argumento para el método estático “. ( fuente )

Un código de ejemplo:

  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 ( 
Hello {this.props.name}
); } }); React.render(, document.body);

Espero que esto te ayude un poco, porque no sé si entendí tu pregunta correctamente, así que corrígeme si la interpreté mal 🙂

Parece que las estáticas están en desuso, y los otros métodos de exposición de algunas funciones con render parecen intrincados. Mientras tanto, esta respuesta de Stack Overflow sobre la depuración de React , aunque parece que hack-y, hizo el trabajo por mí.

Si está en ES6 simplemente use la palabra clave “static” en su método de su ejemplo sería el siguiente: static alertMessage: function() { ...
},
static alertMessage: function() { ...
},

Hope puede ayudar a cualquiera por ahí 🙂

Con el método de render que potencialmente desaprueba el valor devuelto, el enfoque recomendado ahora es adjuntar una callback ref al elemento raíz. Me gusta esto:

 ReactDOM.render(  {window.helloComponent = element}}/>, document.getElementById('container')); 

a la que podemos acceder usando window.helloComponent, y se puede acceder a cualquiera de sus métodos con window.helloComponent.METHOD.

Aquí hay un ejemplo completo:

 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(  {window.helloComponent = element}}/>, document.getElementById('container')); 
   
 class AppProvider extends Component { constructor() { super(); window.alertMessage = this.alertMessage.bind(this); } alertMessage() { console.log('Hello World'); } } 

Puede llamar a este método desde la ventana utilizando window.alertMessage() .