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 FieldEditor
componentes, 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
estado y ponerla en FormEditor
su lugar. Sin embargo, eso requeriría FormEditor
escuchar cada uno de sus FieldEditor
componentes a 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?
javascript
reactjs
Moshe Revah
fuente
fuente
FieldEditor
s por separado, guardar su estado enFormEditor
buen estado. Si este es el caso, susFieldEditor
instancias se procesarán según loprops
aprobado por su editor de formularios, no por el suyostate
. Una forma más compleja pero flexible sería hacer un serializador que pase por cualquier contenedor hijo y encuentre todas lasFormEditor
instancias entre ellos y los serialice en un objeto JSON. El objeto JSON se puede anidar opcionalmente (más de un nivel) en función de los niveles de anidación de las instancias en el editor de formularios.Respuestas:
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:
Original - versión pre-ganchos:
Mostrar fragmento de código
fuente
myAPI.SaveStuff(this.state);
. Si elabora un poco más, tal vez pueda darle una mejor respuesta :)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 con respecto a una mejor solución para manejar este escenario en particular.
Si realmente desea acceder al estado de los elementos
ref
secundarios de un componente, puede asignar una propiedad llamada a cada elemento secundario. Ahora hay dos formas de implementar referencias: UsoReact.createRef()
y referencias de devolución de llamada.Utilizando
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 hijo a través del
ref
atributo.Para acceder a este tipo de referencia, deberá usar:
Esto devolverá una instancia del componente montado para que pueda usarlo
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 una instancia de componente.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:
En estos ejemplos, la referencia se almacena en el componente principal. Para llamar a este componente en su código, puede usar:
y luego usar
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 indicó anteriormente, si usa 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 página de Facebook.
Asegúrese de leer la sección "No usar en exceso las referencias " que dice que no debe usar al niño
state
para "hacer que las cosas sucedan".Espero que esto ayude ^ _ ^
Editar:
React.createRef()
Método agregado para crear referencias. Se eliminó el código ES5.fuente
this.refs.yourComponentNameHere
. Lo he encontrado útil para cambiar el estado a través de funciones. Ejemplo:this.refs.textInputField.clearInput();
props
ystate
. Sin embargo, no deberían ser su abstracción para el flujo de datos a través de su aplicación. Por defecto, use el flujo de datos reactivos y guarderef
s para casos de uso que son inherentemente no reactivos.connected
componente Redux ?Es 2020 y muchos de ustedes vendrán aquí buscando una solución similar pero con ganchos (¡son geniales!) Y con los últimos enfoques en términos de limpieza y sintaxis del código.
Entonces, como habían dicho las respuestas anteriores, el mejor enfoque para este tipo de problema es mantener el estado fuera del componente secundario
fieldEditor
. Podrías hacerlo de múltiples maneras.El más "complejo" es el contexto global (estado) al que tanto padres como hijos pueden acceder y modificar. Es una gran solución cuando los componentes están muy arraigados en la jerarquía del árbol y, por lo tanto, es costoso enviar accesorios en cada nivel.
En este caso, creo que no vale la pena, y un enfoque más simple nos traerá los resultados que queremos, simplemente usando los poderosos
React.useState()
.Enfoque con el gancho React.useState (), mucho más simple que con los componentes de la Clase
Como se dijo, trataremos los cambios y almacenaremos los datos de nuestro componente hijo
fieldEditor
en nuestro padrefieldForm
. Para hacerlo, enviaremos una referencia a la función que se ocupará y aplicará los cambios alfieldForm
estado, puede hacerlo con:Tenga en cuenta que
React.useState({})
devolverá una matriz con la posición 0 como valor especificado en la llamada (objeto vacío en este caso) y la posición 1 como referencia a la función que modifica el valor.Ahora con el componente hijo,
FieldEditor
ni siquiera necesita crear una función con una declaración de retorno, ¡una constante lean con una función de flecha servirá!Aaaa y hemos terminado, nada más, con estos dos componentes funcionales de limo tenemos nuestro objetivo final "acceder" a nuestro
FieldEditor
valor hijo y mostrarlo en nuestros padres.Puede verificar la respuesta aceptada de hace 5 años y ver cómo Hooks hizo que React code sea más ágil (¡por mucho!).
Espero que mi respuesta te ayude a aprender y comprender más sobre Hooks, y si quieres ver un ejemplo de trabajo aquí está .
fuente
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.
fuente
Como dicen las respuestas anteriores, intente mover el estado a un componente superior y modificar el estado a través de las devoluciones de llamada pasadas a sus hijos.
En caso de que realmente necesite acceder a un estado secundario que se declara como un componente funcional (ganchos), puede declarar una referencia en el componente principal, luego pasarla como un atributo de referencia al elemento secundario, pero debe usar React.forwardRef y luego el gancho useImperativeHandle para declarar una función que puede llamar en el componente padre.
Eche un vistazo al siguiente ejemplo:
Entonces debería poder obtener myState en el componente primario llamando a:
myRef.current.getMyState();
fuente