tutorial react instalar hello example español ejemplos documentacion javascript reactjs

javascript - instalar - ¿Cómo acceder al estado del niño en React?



react js init (3)

Tengo la siguiente estructura:

FormEditor - contiene múltiples FieldEditor FieldEditor - edita un campo del formulario y guarda varios valores al respecto en su estado

Cuando se hace clic en un botón dentro de FormEditor, quiero poder recopilar información sobre los campos de todos los componentes de FieldEditor , información que está en su estado, y tenerlo todo dentro de FormEditor.

Pensé en almacenar la información sobre los campos fuera del FieldEditor de FieldEditor y en su lugar la puse en el estado de FormEditor . Sin embargo, eso requeriría que FormEditor escuchara cada uno de FieldEditor componentes FieldEditor medida que cambian y almacenan su información en su estado.

¿No puedo acceder al estado de los niños en su lugar? ¿Es ideal?


Ahora puede acceder al estado de InputField que es el hijo de FormEditor.

Básicamente, cada vez que hay un cambio en el estado del campo de entrada (secundario), obtenemos el valor del objeto de evento y luego pasamos este valor al Principal donde se establece el estado en el Principal.

Al hacer clic en el botón, solo estamos imprimiendo el estado de los campos de entrada.

El punto clave aquí es que estamos usando los accesorios para obtener el id / valor del campo de entrada y también para llamar a las funciones que se establecen como atributos en el campo de entrada mientras generamos los campos de entrada secundarios reutilizables.

class InputField extends React.Component{ handleChange = (event)=> { const val = event.target.value; this.props.onChange(this.props.id , val); } render() { return( <div> <input type="text" onChange={this.handleChange} value={this.props.value}/> <br/><br/> </div> ); } } class FormEditorParent extends React.Component { state = {}; handleFieldChange = (inputFieldId , inputFieldValue) => { this.setState({[inputFieldId]:inputFieldValue}); } //on Button click simply get the state of the input field handleClick = ()=>{ console.log(JSON.stringify(this.state)); } render() { const fields = this.props.fields.map(field => ( <InputField key={field} id={field} onChange={this.handleFieldChange} value={this.state[field]} /> )); return ( <div> <div> <button onClick={this.handleClick}>Click Me</button> </div> <div> {fields} </div> </div> ); } } const App = () => { const fields = ["field1", "field2", "anotherField"]; return <FormEditorParent fields={fields} />; }; ReactDOM.render(<App/>, mountNode);


Justo antes de entrar en detalles sobre cómo puede acceder al estado de un componente secundario, asegúrese de leer la respuesta de Markus-ipse respecto a una mejor solución para manejar este escenario en particular.

Si realmente desea acceder al estado de los elementos secundarios de un componente, puede asignar una propiedad llamada ref a cada elemento secundario. Ahora hay dos formas de implementar referencias: utilizando React.createRef() y referencias de devolución de llamada.

Usando React.createRef()

Esta es actualmente la forma recomendada de utilizar referencias a partir de React 16.3 (consulte los documentos para obtener más información). Si está utilizando una versión anterior, consulte a continuación las referencias de devolución de llamada.

Deberá crear una nueva referencia en el constructor de su componente principal y luego asignarla a un elemento secundario a través del atributo ref .

class FormEditor extends React.Component { constructor(props) { super(props); this.FieldEditor1 = React.createRef(); } render() { return <FieldEditor ref={this.FieldEditor1} />; } }

Para acceder a este tipo de referencia, deberá usar:

const currentFieldEditor1 = this.FieldEditor1.current;

Esto devolverá una instancia del componente montado para que pueda usar currentFieldEditor1.state para acceder al estado.

Solo una nota rápida para decir que si usa estas referencias en un nodo DOM en lugar de un componente (por ejemplo, <div ref={this.divRef} /> ), this.divRef.current devolverá el elemento DOM subyacente en lugar de un componente ejemplo.

Referencia de devolución de llamada

Esta propiedad toma una función de devolución de llamada a la que se le pasa una referencia al componente adjunto. Esta devolución de llamada se ejecuta inmediatamente después de que el componente esté montado o desmontado.

Por ejemplo:

<FieldEditor ref={(fieldEditor1) => {this.fieldEditor1 = fieldEditor1;} {...props} />

En estos ejemplos, la referencia se almacena en el componente principal. Para llamar a este componente en su código, puede usar:

this.fieldEditor1

y luego use this.fieldEditor1.state para obtener el estado.

Una cosa a tener en cuenta, asegúrese de que su componente hijo se haya procesado antes de intentar acceder a él ^ _ ^

Como se <div ref={(divRef) => {this.myDiv = divRef;}} /> anteriormente, si utiliza estas referencias en un nodo DOM en lugar de un componente (por ejemplo, <div ref={(divRef) => {this.myDiv = divRef;}} /> ), this.divRef devolverá el elemento DOM subyacente en lugar de una instancia de componente.

Más información

Si desea leer más sobre la propiedad de referencia de React, consulte esta page de Facebook.

Asegúrese de leer la sección "No usar en exceso las referencias " que dice que no debe usar el state del niño para "hacer que las cosas sucedan".

Espero que esto ayude ^ _ ^

Editar: Se React.createRef() método React.createRef() para crear referencias. Se eliminó el código ES5.


Si ya tiene el controlador onChange para los FieldEditors individuales, no entiendo por qué no puede simplemente mover el estado al componente FormEditor y simplemente pasar una devolución de llamada desde allí a los FieldEditors que actualizarán el estado principal. Para mí, esa es una forma más Reactiva de hacerlo.

Algo en la línea de esto quizás:

class FieldEditor extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); } handleChange(event) { const text = event.target.value; this.props.onChange(this.props.id, text); } render() { return ( <div className="field-editor"> <input onChange={this.handleChange} value={this.props.value} /> </div> ); } } class FormEditor extends React.Component { constructor(props) { super(props); this.state = {}; this.handleFieldChange = this.handleFieldChange.bind(this); } handleFieldChange(fieldId, value) { this.setState({ [fieldId]: value }); } render() { const fields = this.props.fields.map(field => ( <FieldEditor key={field} id={field} onChange={this.handleFieldChange} value={this.state[field]} /> )); return ( <div> {fields} <div>{JSON.stringify(this.state)}</div> </div> ); } } // Convert to class component and add ability to dynamically add/remove fields by having it in state const App = () => { const fields = ["field1", "field2", "anotherField"]; return <FormEditor fields={fields} />; }; ReactDOM.render(<App />, document.body);

http://jsbin.com/qeyoxobixa/edit?js,output

Editar: solo por el gusto de hacerlo, he reescrito el ejemplo anterior usando ganchos para cualquier persona interesada:

const FieldEditor = ({ value, onChange, id }) => { const handleChange = event => { const text = event.target.value; onChange(id, text); }; return ( <div className="field-editor"> <input onChange={handleChange} value={value} /> </div> ); }; const FormEditor = props => { const [values, setValues] = useState({}); const handleFieldChange = (fieldId, value) => { setValues({ ...values, [fieldId]: value }); }; const fields = props.fields.map(field => ( <FieldEditor key={field} id={field} onChange={handleFieldChange} value={values[field]} /> )); return ( <div> {fields} <pre>{JSON.stringify(values, null, 2)}</pre> </div> ); }; // To add abillity to dynamically add/remove fields keep the list in state const App = () => { const fields = ["field1", "field2", "anotherField"]; return <FormEditor fields={fields} />; };