Nota: no estoy usando Redux (solo Context + Hooks)
Tengo una pantalla " Perfil ", que representa un TabView .
Este TabView representa dos componentes como escenas:
La pantalla Mi perfil obtiene los datos del usuario de mi base de datos, ya que tiene que generar algunas cosas que dependen de estos datos.
Además, se transmite a través de accesorios a mi componente " Información de usuario", ya que solo representa los datos del usuario. Entonces... no hay obtención de datos en mi componente " Información de usuario".
Por otro lado, mi componente " UserPosts " es responsable de buscar las publicaciones de los usuarios, ya que genera un componente " UserPostsGrid " que representa esas publicaciones con paginación (Lista plana sin fin).
Nota: La obtención de datos se realiza en ganchos personalizados, no directamente dentro del componente (además, esos ganchos administran los datos con estado respectivos).
El principal problema surge cuando necesito actualizar los datos del usuario y el usuario publica cuando el usuario tira para actualizar dentro de la pantalla " Perfil ".
No hay problema para que esta pantalla obtenga los datos del usuario, como he dicho antes, la pantalla " Perfil " es responsable de esa acción.
Pero las publicaciones son los datos con estado de mi hijo...
He pensado en resolver este problema usando la solución actual:
React.forwardRef() + React.useImperativeHandle()
Con esto, podré pasar una referencia a mis " UserPosts " y usar la programación imperativa para acceder al método de obtención de datos: userPostsRef.current.refreshPosts();
Nunca he visto otros escenarios para resolver este problema como este, pero debería funcionar. En cambio, otros codificadores implementan un ContextProvider para manejar todos los datos y poder acceder a ellos donde quieran. El principal problema que noto aquí es: memoización adicional + renderizaciones adicionales.
Otra solución podría ser implementar toda la obtención de datos dentro del padre y pasar las respectivas devoluciones de llamada a través de accesorios al hijo. El principal problema que noto aquí es que estamos creando algún tipo de "Componente de Dios" y es posible que tengamos varias líneas de código...
¿Es un antipatrón o una mala práctica implementar la primera solución ?
Sí, es un antipatrón en React , porque React se basa en la idea de que usted especifica el estado de su aplicación y luego deja que React represente los componentes dependiendo de este estado dado.
Si algo debe cambiar, se supone que debe especificar un nuevo estado que represente la diferencia con el estado anterior.
Las referencias solo deben usarse si no hay otra opción. Básicamente, si usa Refs, dice "No quiero usar React para esta parte específica de mi código".
Como siempre, el código imperativo que usa referencias debe evitarse en la mayoría de los casos.
Abordaría este tipo de problema tratando de traducir la acción imperativa en algún estado de información .
Por ejemplo, puede usar un accesorio needsUpdate
, que se establece en true
cuando los datos deben actualizarse y en false
cuando se recuperan.
Para evitar representaciones innecesarias (la configuración de needsUpdate = false
causaría otra llamada de, por ejemplo, useEffect, incluso si no sucede nada allí), probablemente usaría un accesorio de componente secundario como latestUpdateRequest
y un estado secundario como latestUpdate
que contiene un contador o una marca de tiempo, y luego comparar if(latestUpdateRequest > latestUpdate)
.
Para informar al padre sobre el cambio, simplemente pase una función de devolución de llamada como dataUpdated()
como apoyo.