React Native
Relay (GraphQL)
Implementación Relay QueryRenderer with Back4App en React Native
30 min
renderizador de consultas en back4app introducción en nuestra guía , hemos aprendido cómo preparar nuestro entorno relay ahora estás listo para comenzar a desarrollar tu aplicación react native en esta guía, aprenderás cómo hacer tu primera consulta en back4app vamos a profundizar en el renderizador de consultas relay, entendiendo sus principios principales y usándolo para consumir tus primeros datos de back4app objetivos obtener una visión general del renderizador de consultas relay; hacer una consulta en la api graphql de back4app desde una aplicación react native usando relay; requisitos previos aplicación creada en el panel de control de back4app aplicación react native y con el entorno relay configurado por la documentación anterior leer sobre relay node y conexiones ¿qué es el renderizador de consultas? así como react construye un árbol de componentes, relay construye un árbol de componentes de datos esto significa que cada componente de la aplicación será el propietario de sus datos de fragmento el fragmento contendrá la información de datos necesaria para renderizarlo en pantalla y relay asegura que estos datos estén disponibles antes de renderizar el componente manejando todo este enfoque, el renderizador de consultas es un componente raíz necesario para componer esos fragmentos y preparar la consulta para ser recuperada de nuestro back end ¿por qué entender el renderizador de consultas? entender el uso del renderizador de consultas hace que sea importante abstraer tu aplicación de diferentes maneras una buena abstracción de código podría prevenir horas de trabajo, errores, tiempo de depuración, etc cómo funciona el renderizador junto con las apis de back4app en el último tutorial, hemos preparado el archivo del entorno relay, que especifica la información de conexión de back4app usando esta configuración, relay se encargará de la comunicación con las apis de back4app no necesitas preocuparte por la conexión solo concéntrate en construir los componentes de datos 1 creando una clase en el panel de control de back4app vamos a crear tu primera clase y poblarla con algunos objetos usando la consola graphql de back4app la clase persona tiene 2 campos nombre, que es una cadena, y salario, que es un entero ve al panel de control >núcleo >consola graphql y usa el código a continuación 1 mutation createclass { 2 createclass(input { 3 name "person" 4 schemafields { 5 addstrings \[{name "name"}] 6 addnumbers \[{name "salary"}] 7 } 8 }){ 9 class{ 10 schemafields{ 11 name 12 typename 13 } 14 } 15 } 16 } verás el resultado a continuación creando clase ahora vamos a crear algunos objetos dentro de esta clase ve a la mutación de crear objeto guía https //www back4app com/docs/parse graphql/graphql mutation create object#mutation generic y ve cómo manejar este caso asegúrate de estar utilizando la última versión de parse server para poder usar la notación más reciente de la api graphql disponible en back4app 1 mutation createobject{ 2 createhero(input {fields {name "allana foley", salary 1000}}){ 3 person { 4 id 5 name 6 salary 7 } 8 } 9 } creando objeto ahora, la clase persona está creada y tiene un campo de nombre y salario después de crear una nueva clase, back4app genera automáticamente todos los recursos necesarios para usar el back end de manera segura un ejemplo es la lista de objetos back4app ya creó las conexiones necesarias para consultar la lista de personas personas para entender mejor, ve al playground, actualiza y abre la pestaña de docs y busca personas back4app generó el campo de conexión también puedes consultar la clase persona como una lista ten en cuenta que el campo query people es una personconnection relay consumirá el campo de conexión para renderizar una lista de los objetos de la persona documento del campo persona y la documentación del campo de conexión personas (persona) 2 actualizando el esquema es importante recordar que si una nueva clase entra en tu aplicación, será necesario actualizar el esquema dentro de la raíz de la aplicación react native si es necesario, ve a descargar esquema docs y repite los pasos para actualizar el esquema 3 primer ejemplo de contenedor de fragmentos antes de continuar con el tutorial, vamos a presentarte el contenedor de fragmentos vamos a crear un componente que será el propietario de la información de la persona este componente contendrá el nombre y el salario de la persona aquí puedes pedir cualquier campo de persona para construir tu componente ahora, vamos a proceder con estos dos campos crea un archivo y nómbralo personcard js personcard js dentro de él, vamos a crear un componente de función simple 1 import react from 'react'; 2	 3 const personcard = () => { 4 return ( 5 \<div> 6 7 \</div> 8 ); 9 }; reemplace la línea de export default por el código de abajo 1 export default createfragmentcontainer(personcard, { 2 person graphql` 3 fragment personcard person on person { 4 id 5 name 6 salary 7 } 8 `, 9 }); el código de arriba creará un fragmento de una persona que solo pide id, nombre y salario termine de actualizar el resto del componente con el siguiente código 1 const personcard = ({person}) => { 2 return ( 3 \<view> 4 \<text>name {person name}\</text> 5 \<text>salary {person salary}\</text> 6 \</view> 7 ); 8 }; el resultado final debería verse así 1 import react from "react"; 2 import { createfragmentcontainer, graphql } from "react relay"; 3 import { view, text } from "react native"; 4	 5 const personcard = ({person}) => { 6 return ( 7 \<view> 8 \<text>name {person name}\</text> 9 \<text>salary {person salary}\</text> 10 \</view> 11 ); 12 }; 13	 14 export default createfragmentcontainer(personcard, { 15 person graphql` 16 fragment personcard person on person { 17 id 18 name 19 salary 20 } 21 `, 22 }); 4 creando el renderizador de consultas el siguiente paso es crear el renderizador de consultas para tu lista de objetos el renderizador de consultas es un componente raíz para recuperar los componentes de datos y prepararlos para obtener datos del backend aprenderás cómo recuperar datos para una clase de persona en back4app 4 1 creando el archivo crea un nuevo archivo y nómbralo personrenderer js personrenderer js copia el código a continuación y pégalo en el archivo personrenderer 1 const personrenderer = () => { 2 return ( 3 \<queryrenderer 4 environment={environment} 5 query={graphql``} 6 variables={null} 7 render={({error, props}) => { 8 if (error) { 9 return ( 10 \<view> 11 \<text>{error message}\</text> 12 \</view> 13 ); 14 } else if (props) { 15 // @todo here will be implement the person card for each item from result 16 } 17 return ( 18 \<view> 19 \<text>loading\</text> 20 \</view> 21 ); 22 }} 23 /> 24 ); 25 }; 26	 27 export default personrenderer; 4 2 entendiendo las propiedades de queryrenderer comencemos con un query renderer con sus propiedades vacías graphql, variables y render paso a paso, implementarás cada uno de manera incremental primero que nada, tu aplicación necesita informar la consulta para query renderer aquí, nuestra aplicación consumirá una lista de personas en las propiedades de la consulta, pega el siguiente código 1 graphql` 2 query personrendererquery { 3 people { 4 edges { 5 node { 6 personcard person 7 } 8 } 9 } 10 }` el graphql proviene de react relay e implementa la consulta como una cadena es importante entender las conexiones de edges y nodes la consulta anterior está consumiendo una conexión de nodos de personas del servidor back4app cada vez que creas una nueva clase, estará seguida de una conexión de nodos variables cuando sea necesario, el renderizador de consultas consumirá variables un buen ejemplo cuando la aplicación solicita una consulta para una persona por id como este no es el caso en este momento, dejemos las propiedades de variables en null poblando la tarjeta de persona esta consulta devolverá una lista de personas el renderizador de consultas asegura que los datos estarán disponibles para renderizar si no lo están, se generará un error la propiedad responsable de esto es el render puebla las propiedades de render con el siguiente código 1 render={({error, props}) => { 2 if (error) { 3 return ( 4 \<view> 5 \<text>{error message}\</text> 6 \</view> 7 ); 8 } else if (props) { 9 return props people edges map(({node}) => \<personcard person={node} />); 10 } 11 return ( 12 \<view> 13 \<text>loading\</text> 14 \</view> 15 ); 16 }} reemplaza el todo comentado por un mapa de javascript para renderizar una tarjeta de persona para cada resultado de la lista como se dijo, el renderizador de consultas se encarga de hacer que los datos estén disponibles solo cuando estén listos hasta entonces, se mostrará un mensaje de carga si ocurre un error, se mostrará en la pantalla evitando un cierre inesperado de la aplicación por último, mejoremos el renderizado de personas reemplazando el map por una nueva función colóquelo antes del query renderer 1 const renderpersons = (people) => { 2 return people edges map(({node}) => \<personcard person={node} />); 3 }; y el resultado final debería verse así 1 import react from "react"; 2 import { queryrenderer } from "react relay"; 3 import environment from " /relay/environment"; 4 import personcard from " /personcard"; 5 import { view, text } from "react native"; 6	 7 const personrenderer = () => { 8 const renderpersons = (people) => { 9 return people edges map(({node}) => \<personcard person={node} />); 10 }; 11	 12 return ( 13 \<queryrenderer 14 environment={environment} 15 query={graphql` 16 query personrendererquery { 17 people { 18 edges { 19 node { 20 personcard person 21 } 22 } 23 } 24 } 25 `} 26 variables={null} 27 render={({error, props}) => { 28 if (error) { 29 return ( 30 \<view> 31 \<text>{error message}\</text> 32 \</view> 33 ); 34 } else if (props) { 35 return renderpersons(props people); 36 } 37 return ( 38 \<view> 39 \<text>loading\</text> 40 \</view> 41 ); 42 }} 43 /> 44 ); 45 }; 46	 47 export default personrenderer; 5 haciendo tu primera consulta ahora es el momento de obtener la persona usando el personrenderer si todo está bien, tu aplicación ahora tiene dos nuevos componentes personrenderer y personcard antes de iniciar la aplicación, relay necesita que el relay compiler se ejecute y genere los tipos de componentes para esto, ejecuta en tu terminal en app js agrega el siguiente código 1 import react from 'react'; 2 import { safeareaview, statusbar, view, text } from 'react native'; 3	 4 import providers from ' /providers'; 5 import personrenderer from ' /components/home/person/personrenderer'; 6	 7 const app = () => { 8 return ( 9 \<providers> 10 \<statusbar barstyle="dark content" /> 11 \<safeareaview> 12 \<view 13 style={ { 14 flexdirection 'column', 15 justifycontent 'center', 16 alignitems 'center', 17 margintop 100, 18 } }> 19 \<text style={ {fontweight "bold", textalign "center"} }> 20 back4app react native relay query renderer list example 21 \</text> 22 \<personrenderer /> 23 \</view> 24 \</safeareaview> 25 \</providers> 26 ); 27 }; 28	 29 export default app; el código de app js proviene originalmente de create react native app agregó una vista con un estilo para centrar el contenido en la pantalla con un margen de 10px desde la parte superior dentro de ella hay un texto con una etiqueta para dar algo de contexto a la impresión y el personrenderer para mostrar la lista de personas necesitas obtener el siguiente resultado renderizado en nuestra aplicación back4app react native, importamos el personrenderer directamente en el app js app js como el personrenderer es un componente raíz y tiene su queryrenderer, la persona debe mostrarse sin ningún error 6 tipando los componentes este paso tiene sentido para una aplicación que trabaja con typescript si tu aplicación no usa typescript, adelante uno de los poderes del relay compiler es generar los tipos de cada componente de datos vamos a tipar el personrenderer y el personcard para hacer la aplicación más poderosa tipando personrenderer tipa el argumento de la función renderperson people people en personrenderer 1 const renderpersons = (people personrendererquery\['response']\['people']) => { 2 return people edges map(({node}) => \<personcard person={node} />); 3 }; importa el personrendererquery personrendererquery tipo de generated generated carpeta creada dentro de la misma carpeta del personrenderer tipando personcard ve a personcard, crea un nuevo objeto de tipo y nómbralo personcardprops 1 type personcardprops = {}; importa el personcard person personcard person tipo de generated generated carpetas 1 import {personcard person} from ' / generated /personcard person graphql'; agrega la persona dentro del tipo personcardprops 1 type personcardprops = { 2 person personcard person; 3 }; en los argumentos de props de personcard, tipa el componente con el personcardprops personcardprops el resultado final de ambos componentes debería verse así personrenderer 1 import react from 'react'; 2 import {graphql, queryrenderer} from 'react relay'; 3 import {environment} from ' / / /relay'; 4 import personcard from ' /personcard'; 5 import {view, text} from 'react native'; 6 import {personrendererquery} from ' / generated /personrendererquery graphql'; 7	 8 const personrenderer = () => { 9 const renderpersons = (people personrendererquery\['response']\['people']) => { 10 return people edges map(({node}) => \<personcard person={node} />); 11 }; 12	 13 return ( 14 \<queryrenderer 15 environment={environment} 16 query={graphql` 17 query personrendererquery { 18 people { 19 edges { 20 node { 21 personcard person 22 } 23 } 24 } 25 } 26 `} 27 variables={null} 28 render={({error, props}) => { 29 if (error) { 30 return ( 31 \<view> 32 \<text>{error message}\</text> 33 \</view> 34 ); 35 } else if (props) { 36 return renderpersons(props people); 37 } 38 return ( 39 \<view> 40 \<text>loading\</text> 41 \</view> 42 ); 43 }} 44 /> 45 ); 46 }; 47	 48 export default personrenderer; personcard 1 import react from 'react'; 2	 3 import {createfragmentcontainer, graphql} from 'react relay'; 4	 5 import {view, text} from 'react native'; 6 import {personcard person} from ' / generated /personcard person graphql'; 7	 8 type personcardprops = { 9 person personcard person; 10 }; 11	 12 const personcard = ({person} personcardprops) => { 13 return ( 14 \<view> 15 \<text>name {person name}\</text> 16 \<text>salary {person salary}\</text> 17 \</view> 18 ); 19 }; 20	 21 export default createfragmentcontainer(personcard, { 22 person graphql` 23 fragment personcard person on person { 24 id 25 name 26 salary 27 } 28 `, 29 }); conclusión el resultado final de queryrenderer demostró cómo se puede abstraer la aplicación la aplicación puede mostrar la persona dentro del query renderer como el personcard tiene más componentes, no cambia la forma en que se construyó el query renderer el personrenderer fue construido para mostrar cómo se puede realizar una consulta en pasos fáciles, combinado con el poder del servidor back4app en la próxima guía, aprenderás cómo recuperar un objeto persona específico y mostrar sus atributos