tutorial react hello example español ejemplos javascript reactjs

javascript - hello - react js tutorial español



Pasar accesorios al componente principal en React.js (6)

Aquí hay una implementación simple de ES6 de 3 pasos utilizando la función de enlace en el constructor principal. Esta es la primera forma en que recomienda el tutorial de reacción oficial (también hay sintaxis de campos de clase pública que no se trata aquí). Puede encontrar toda esta información aquí https://reactjs.org/docs/handling-events.html

Funciones obligatorias de los padres para que los niños puedan llamarlos (¡y pasar los datos a los padres !: D)

  1. Asegúrese de que en el constructor principal enlace la función que creó en el principal
  2. Pase la función enlazada al niño como apoyo (no lambda porque estamos pasando una referencia a la función)
  3. Llame a la función enlazada desde un evento secundario (Lambda! Estamos llamando a la función cuando se activa el evento. Si no lo hacemos, la función se ejecutará automáticamente en carga y no se activará en el evento).

Función de los padres

handleFilterApply(filterVals){}

Constructor Padre

this.handleFilterApply = this.handleFilterApply.bind(this);

Prop. Pasado al niño

onApplyClick = {this.handleFilterApply}

Llamada de evento infantil

onClick = {() => {props.onApplyClick(filterVals)}

¿No hay una forma sencilla de pasarle los props un niño a su padre usando eventos, en React.js?

var Child = React.createClass({ render: function() { <a onClick={this.props.onClick}>Click me</a> } }); var Parent = React.createClass({ onClick: function(event) { // event.component.props ?why is this not available? }, render: function() { <Child onClick={this.onClick} /> } });

Sé que puedes usar componentes controlados para pasar el valor de una entrada, pero sería bueno pasar todo el kit n ''kaboodle. A veces, el componente secundario contiene un conjunto de información que preferiría no tener que buscar.

Tal vez hay una manera de vincular el componente al evento?

ACTUALIZACIÓN - 9/1/2015

Después de usar React por más de un año, y estimulado por la respuesta de Sebastien Lorber, he concluido que pasar componentes secundarios como argumentos a las funciones en los padres no es en realidad el modo React, ni tampoco fue una buena idea. He cambiado la respuesta.


La pregunta es cómo pasar el argumento del componente hijo al padre. Este ejemplo es fácil de usar y probado:

//Child component class Child extends React.Component { render() { var handleToUpdate = this.props.handleToUpdate; return (<div><button onClick={() => handleToUpdate(''someVar'')}>Push me</button></div> ) } } //Parent component class Parent extends React.Component { constructor(props) { super(props); var handleToUpdate = this.handleToUpdate.bind(this); } handleToUpdate(someArg){ alert(''We pass argument from Child to Parent: /n'' + someArg); } render() { var handleToUpdate = this.handleToUpdate; return (<div> <Child handleToUpdate = {handleToUpdate.bind(this)} /></div>) } } if(document.querySelector("#demo")){ ReactDOM.render( <Parent />, document.querySelector("#demo") ); }

Mira JSFIDDLE


Parece que hay una respuesta simple. Considera esto:

var Child = React.createClass({ render: function() { <a onClick={this.props.onClick.bind(null, this)}>Click me</a> } }); var Parent = React.createClass({ onClick: function(component, event) { component.props // #=> {Object...} }, render: function() { <Child onClick={this.onClick} /> } });

La clave está llamando a bind(null, this) en el evento this.props.onClick , que se pasa desde el padre. Ahora, la función onClick acepta component argumentos, Y event . Creo que eso es lo mejor de todos los mundos.

ACTUALIZACIÓN: 9/1/2015

Esta fue una mala idea: dejar que los detalles de la implementación del niño se filtraran a los padres nunca fue un buen camino. Ver la respuesta de Sebastien Lorber.


Actualización (9/1/15): El OP ha hecho de esta pregunta un poco un objetivo en movimiento. Se ha actualizado de nuevo. Por lo tanto, me siento responsable de actualizar mi respuesta.

Primero, una respuesta a su ejemplo proporcionado:

Sí, esto es posible.

Puedes resolver esto actualizando Child''s onClick para ser this.props.onClick.bind(null, this) :

var Child = React.createClass({ render: function () { return <a onClick={this.props.onClick.bind(null, this)}>Click me</a>; } });

El controlador de eventos en su padre puede acceder al componente y al evento de la siguiente manera:

onClick: function (component, event) { // console.log(component, event); },

Instantánea de JSBin


Pero la pregunta en sí es engañosa.

El padre ya sabe los props del niño.

Esto no está claro en el ejemplo proporcionado porque en realidad no se proporcionan apoyos. Este código de ejemplo podría apoyar mejor la pregunta que se hace:

var Child = React.createClass({ render: function () { return <a onClick={this.props.onClick}> {this.props.text} </a>; } }); var Parent = React.createClass({ getInitialState: function () { return { text: "Click here" }; }, onClick: function (event) { // event.component.props ?why is this not available? }, render: function() { return <Child onClick={this.onClick} text={this.state.text} />; } });

En este ejemplo queda mucho más claro que ya sabe cuáles son los accesorios de Child.

Instantánea de JSBin


Si realmente se trata de usar los accesorios de un niño ...

Si realmente se trata de usar los accesorios de un Niño, puedes evitar cualquier conexión con el Niño por completo.

JSX tiene una API de atributos extendidos que uso a menudo en componentes como Child. Toma todos los props y los aplica a un componente. El niño se vería así:

var Child = React.createClass({ render: function () { return <a {...this.props}> {this.props.text} </a>; } });

Permitiéndole usar los valores directamente en el Padre:

var Parent = React.createClass({ getInitialState: function () { return { text: "Click here" }; }, onClick: function (text) { alert(text); }, render: function() { return <Child onClick={this.onClick.bind(null, this.state.text)} text={this.state.text} />; } });

Instantánea de JSBin


Y no se requiere configuración adicional a medida que conectas componentes secundarios adicionales

var Parent = React.createClass({ getInitialState: function () { return { text: "Click here", text2: "No, Click here", }; }, onClick: function (text) { alert(text); }, render: function() { return <div> <Child onClick={this.onClick.bind(null, this.state.text)} text={this.state.text} /> <Child onClick={this.onClick.bind(null, this.state.text2)} text={this.state.text2} /> </div>; } });

Instantánea de JSBin

Pero sospecho que no es su caso de uso real. Así que vamos a profundizar más ...


Un ejemplo práctico robusto.

Es difícil hablar de la naturaleza genérica del ejemplo proporcionado. He creado un componente que demuestra un uso práctico de la pregunta anterior, implementado de una manera muy reactiva :

Ejemplo de trabajo de DTServiceCalculator
DTServiceCalculator repo

Este componente es una calculadora de servicio simple. Le proporciona una lista de servicios (con nombres y precios) y calculará un total de los precios seleccionados.

Los niños son felizmente ignorantes

ServiceItem es el componente hijo en este ejemplo. No tiene muchas opiniones sobre el mundo exterior. Requiere algunos accesorios , uno de los cuales es una función a la que se debe llamar cuando se hace clic.

<div onClick={this.props.handleClick.bind(this.props.index)} />

No hace nada más que llamar a la devolución de llamada handleClick proporcionada con el index proporcionado [ source ].

Los padres son hijos

DTServicesCalculator es el componente principal en este ejemplo. También es un niño. Miremos.

DTServiceCalculator crea una lista de componentes ServiceItem ( ServiceItem s) y les proporciona los accesorios [ source ]. Es el componente principal de ServiceItem pero es el componente secundario del componente que le pasa la lista. No posee los datos. Así que otra vez delega el manejo del componente a su source componente principal

<ServiceItem chosen={chosen} index={i} key={id} price={price} name={name} onSelect={this.props.handleServiceItem} />

handleServiceItem captura el índice, se pasa del elemento secundario y lo proporciona a su principal [ source ]

handleServiceClick (index) { this.props.onSelect(index); }

Los propietarios lo saben todo.

El concepto de "Propiedad" es importante en React. Recomiendo leer más sobre esto here .

En el ejemplo que he mostrado, sigo delegando el manejo de un evento en el árbol de componentes hasta que lleguemos al componente que posee el estado.

Cuando finalmente lleguemos allí, manejamos la selección / deselección de estados como [ source ]:

handleSelect (index) { let services = […this.state.services]; services[index].chosen = (services[index].chosen) ? false : true; this.setState({ services: services }); }


Conclusión

Intente mantener los componentes más externos lo más opacos posible. Trate de asegurarse de que tengan muy pocas preferencias sobre cómo un componente principal podría elegir implementarlos.

Manténgase al tanto de quién es el propietario de los datos que está manipulando. En la mayoría de los casos, deberá delegar el manejo de eventos en el árbol al componente que posee ese estado.

Aparte: el patrón de flujo es una buena manera de reducir este tipo de conexión necesaria en las aplicaciones.


Básicamente, usas accesorios para enviar información hacia y desde Child and Parent.

Agregando a todas las respuestas maravillosas, permítanme dar un ejemplo simple que explica los valores pasados ​​del componente hijo al elemento principal en Reaccionar

App.js

class App extends React.Component { constructor(){ super(); this.handleFilterUpdate = this.handleFilterUpdate.bind(this); this.state={name:''igi''} } handleFilterUpdate(filterValue) { this.setState({ name: filterValue }); } render() { return ( <div> <Header change={this.handleFilterUpdate} name={this.state.name} /> <p>{this.state.name}</p> </div> ); } }

Header.js

class Header extends React.Component { constructor(){ super(); this.state={ names: ''jessy'' } } Change(event) { // this.props.change(this.state.names); this.props.change(''jessy''); } render() { return ( <button onClick={this.Change.bind(this)}>click</button> ); } }

Main.js

import React from ''react''; import ReactDOM from ''react-dom''; import App from ''./App.jsx''; ReactDOM.render(<App />, document.getElementById(''app''));

Eso es todo, ahora puede pasar valores de su cliente al servidor.

Eche un vistazo a la función de cambio en Header.js

Change(event) { // this.props.change(this.state.names); this.props.change(''jessy''); }

Así es como se introducen los valores en las propiedades del cliente al servidor.


Editar : ver los ejemplos finales para los ejemplos actualizados de ES6.

Esta respuesta simplemente maneja el caso de relación directa entre padres e hijos. Cuando padre e hijo tienen potencialmente muchos intermediarios, verifique esta answer .

Otras soluciones faltan el punto

Si bien todavía funcionan bien, a otras respuestas les falta algo muy importante.

¿No hay una forma sencilla de pasarle los apoyos de un niño a su padre usando eventos, en React.js?

¡El padre ya tiene ese apoyo infantil! : si el niño tiene un apoyo, entonces es porque su padre le proporcionó ese apoyo al niño! ¿Por qué quiere que el niño le pase el apoyo al padre, mientras que el padre obviamente ya tiene ese apoyo?

Mejor implementación

Niño : realmente no tiene que ser más complicado que eso.

var Child = React.createClass({ render: function () { return <button onClick={this.props.onClick}>{this.props.text}</button>; }, });

Padre con hijo único : usando el valor que pasa al niño

var Parent = React.createClass({ getInitialState: function() { return {childText: "Click me! (parent prop)"}; }, render: function () { return ( <Child onClick={this.handleChildClick} text={this.state.childText}/> ); }, handleChildClick: function(event) { // You can access the prop you pass to the children // because you already have it! // Here you have it in state but it could also be // in props, coming from another parent. alert("The Child button text is: " + this.state.childText); // You can also access the target of the click here // if you want to do some magic stuff alert("The Child HTML is: " + event.target.outerHTML); } });

JsFiddle

Padre con lista de hijos : todavía tiene todo lo que necesita sobre el padre y no necesita hacer que el niño sea más complicado.

var Parent = React.createClass({ getInitialState: function() { return {childrenData: [ {childText: "Click me 1!", childNumber: 1}, {childText: "Click me 2!", childNumber: 2} ]}; }, render: function () { var children = this.state.childrenData.map(function(childData,childIndex) { return <Child onClick={this.handleChildClick.bind(null,childData)} text={childData.childText}/>; }.bind(this)); return <div>{children}</div>; }, handleChildClick: function(childData,event) { alert("The Child button data is: " + childData.childText + " - " + childData.childNumber); alert("The Child HTML is: " + event.target.outerHTML); } });

JsFiddle

También es posible usar this.handleChildClick.bind(null,childIndex) y luego usar this.state.childrenData[childIndex]

Tenga en cuenta que estamos vinculando con un contexto null porque, de lo contrario, React emite una advertencia relacionada con su sistema de autobinding automática. Usar nulo significa que no desea cambiar el contexto de la función. Ver tambien

Sobre encapsulación y acoplamiento en otras respuestas.

Esta es para mí una mala idea en términos de acoplamiento y encapsulación:

var Parent = React.createClass({ handleClick: function(childComponent) { // using childComponent.props // using childComponent.refs.button // or anything else using childComponent }, render: function() { <Child onClick={this.handleClick} /> } });

Uso de accesorios : como expliqué anteriormente, ya tienes los accesorios en el padre, por lo que es inútil pasar todo el componente hijo para acceder a los accesorios.

Usando refs : Ya tienes el objetivo de clic en el evento, y en la mayoría de los casos esto es suficiente. Además, podría haber usado una referencia directamente en el niño:

<Child ref="theChild" .../>

Y acceder al nodo DOM en el padre con

React.findDOMNode(this.refs.theChild)

Para casos más avanzados en los que desea acceder a múltiples referencias del hijo en el padre, el hijo podría pasar todos los nodos dom directamente en la devolución de llamada.

El componente tiene una interfaz (accesorios) y el padre no debe asumir nada sobre el funcionamiento interno del niño, incluida su estructura DOM interna o para qué nodos DOM declara refs. Un padre que usa la referencia de un niño significa que acoplas los 2 componentes.

Para ilustrar el problema, tomaré esta cita sobre el DOM Shadow , que se usa dentro de los navegadores para representar cosas como controles deslizantes, barras de desplazamiento, reproductores de video ...

Crearon un límite entre lo que usted, el desarrollador web puede alcanzar y lo que se considera detalles de implementación, por lo tanto, es inaccesible para usted. Sin embargo, el navegador puede atravesar este límite a voluntad. Con este límite en su lugar, fueron capaces de construir todos los elementos HTML utilizando las mismas tecnologías web antiguas, a partir de los divs y vanos, como usted lo haría.

El problema es que si deja que los detalles de la implementación del niño se filtren en el padre, será muy difícil refactorizar al niño sin afectar al padre. Esto significa que, como autor de la biblioteca (o como editor de navegador con Shadow DOM), esto es muy peligroso porque permite que el cliente acceda demasiado, lo que dificulta mucho la actualización del código sin romper la retrocompatibilidad.

Si Chrome hubiera implementado su barra de desplazamiento para permitir que el cliente acceda a los nodos internos de esa barra de desplazamiento, esto significa que el cliente puede simplemente romper esa barra de desplazamiento y que las aplicaciones se romperían más fácilmente cuando Chrome realice su actualización automática después de refactorizar la barra de desplazamiento ... En cambio, solo dan acceso a algunas cosas seguras, como personalizar algunas partes de la barra de desplazamiento con CSS.

Sobre el uso de cualquier otra cosa

Pasar todo el componente en la devolución de llamada es peligroso y puede llevar a los desarrolladores novatos a hacer cosas muy extrañas, como llamar a childComponent.setState(...) o childComponent.forceUpdate() , o asignarle nuevas variables, dentro del padre, haciendo que toda la aplicación mucho más difícil de razonar sobre.

Edición: ejemplos de ES6

Como muchas personas ahora usan ES6, aquí están los mismos ejemplos para la sintaxis de ES6

El niño puede ser muy simple:

const Child = ({ onClick, text }) => ( <button onClick={onClick}> {text} </button> )

El padre puede ser una clase (y eventualmente puede administrar el estado mismo, pero lo estoy aprobando aquí como apoyo):

class Parent1 extends React.Component { handleChildClick(childData,event) { alert("The Child button data is: " + childData.childText + " - " + childData.childNumber); alert("The Child HTML is: " + event.target.outerHTML); } render() { return ( <div> {this.props.childrenData.map(child => ( <Child key={child.childNumber} text={child.childText} onClick={e => this.handleChildClick(child,e)} /> ))} </div> ); } }

Pero también se puede simplificar si no es necesario administrar el estado:

const Parent2 = ({childrenData}) => ( <div> {childrenData.map(child => ( <Child key={child.childNumber} text={child.childText} onClick={e => { alert("The Child button data is: " + child.childText + " - " + child.childNumber); alert("The Child HTML is: " + e.target.outerHTML); }} /> ))} </div> )

JsFiddle

ADVERTENCIA DE PERF (se aplica a ES5 / ES6): si está utilizando PureComponent o shouldComponentUpdate , las implementaciones anteriores no se optimizarán de manera predeterminada porque se usa onClick={e => doSomething()} , o se vincula directamente durante la fase de procesamiento, porque creará una nueva función cada vez que el padre rinda. Si se trata de un cuello de botella en su aplicación, puede pasar los datos a los hijos y reinyectarlos dentro de la devolución de llamada "estable" (establecida en la clase principal, y enlazada a this en el constructor de la clase) para que la optimización PureComponent pueda PureComponent , o puede implementar su propio shouldComponentUpdate e ignorar la devolución de llamada en la verificación de comparación de accesorios.

También puede utilizar la biblioteca Recompose , que proporciona componentes de orden superior para lograr optimizaciones ajustadas:

// A component that is expensive to render const ExpensiveComponent = ({ propA, propB }) => {...} // Optimized version of same component, using shallow comparison of props // Same effect as React''s PureRenderMixin const OptimizedComponent = pure(ExpensiveComponent) // Even more optimized: only updates if specific prop keys have changed const HyperOptimizedComponent = onlyUpdateForKeys([''propA'', ''propB''])(ExpensiveComponent)

En este caso, podría optimizar el componente secundario utilizando:

const OptimizedChild = onlyUpdateForKeys([''text''])(Child)