React Native
Relay (GraphQL)
Query Renderer
30min
query renderer on back4app introduction in our previous guide , we have learned how to prepare our relay environment now you’re ready to start developing your react native app in this guide, you will learn how to make your first query on back4app we’re going to dive into the relay query render, understanding its main principles and use it to consume your first data from back4app goals get an overview of relay query renderer; make a query on back4app graphql api from a react native app using relay; prerequisites application created at back4app dashboard react native application and with relay environment configured by the previous docs read about relay node and connections what is the query renderer? as well as react builds a tree of components, relay builds a tree of data components this means that each component of the application will be the owner of their fragment data the fragment will contain the data information necessary to render it on screen and relay ensures that this data is available before rendering the component handling this whole approach, the query renderer is a root component necessary to compose those fragments and prepare the query to be fetched from our back end why understand the query renderer? understanding the use of query renderer makes it important to abstract your application in different ways a good abstract of code could prevent hours of work, errors, debugging time, etc how it works the renderer together with back4app apis in the last tutorial, we have prepared the relay environment file, which specifies the back4app connection info using this configuration, relay will take care of the communication with back4app apis you don’t need to worry about the connection just focus on building the data components 1 creating a class on back4app dashboard let’s create your first class and populate it with a few objects using the back4app graphql console the person class has 2 fields name which is a string and salary which is an integer go to the dashboard >core >graphql console and use the code below 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 } you’ll see the result below creating class now let’s create some objects inside this class go to the create object mutation guide https //www back4app com/docs/parse graphql/graphql mutation create object#mutation generic and see how to handle this case make sure you are using the latest parse server version in order to use the most recent graphql api notation available on back4app 1 mutation createobject{ 2 createhero(input {fields {name "allana foley", salary 1000}}){ 3 person { 4 id 5 name 6 salary 7 } 8 } 9 } creating object now, the person class is created and has a name and salary field after creating a new class, back4app automatically generates all the necessary resources to use the back end safely one example is the list of objects back4app already created the connections necessary to query the list of person people to better understand, go to the playground, refresh and open the docs tab and look for people back4app generated the connection field you can also query the class person as a list note that the query people field is a personconnection relay will consume the connection field to render a list of the person’s objects person field doc and people (person) connection field docs 2 updating the schema it is important to remember that if a new class goes into your application, it will be necessary to update the schema inside the root of the react native application if necessary, go to download schema docs and repeat the steps to update the schema 3 first example of fragment container before we continue the tutorial, let’s introduce you to the fragment container let’s create a component that will be the person info owner this component will contain the person’s name and salary here you can ask any person field to build your component now, we’re going to proceed with these two fields creates a file and name it personcard js personcard js inside of it, let’s create a simple function component 1 import react from 'react'; 2	 3 const personcard = () => { 4 return ( 5 \<div> 6 7 \</div> 8 ); 9 }; replace the line of export default by the code below 1 export default createfragmentcontainer(personcard, { 2 person graphql` 3 fragment personcard person on person { 4 id 5 name 6 salary 7 } 8 `, 9 }); the code above will create a fragment of a person that asks only for id, name, and salary finish updating the rest of the component with the following code 1 const personcard = ({person}) => { 2 return ( 3 \<view> 4 \<text>name {person name}\</text> 5 \<text>salary {person salary}\</text> 6 \</view> 7 ); 8 }; the final result should look like this 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 creating the query renderer the next step is to create the query renderer for your objects list the query renderer is a root component for retrieving the data components and preparing them to fetch data from the backend you will learn how to retrieve data for a person class on back4app 4 1 creating the file create a new file and name it personrenderer js personrenderer js copy the code below and paste it into personrenderer file 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 understanding the props of queryrenderer let’s start with a query renderer with their props empty graphql, variables, and render step by step, you will implement each one incrementally first of all, your application needs to inform the query for query renderer here, our application will consume a list of people on query props, paste the following code 1 graphql` 2 query personrendererquery { 3 people { 4 edges { 5 node { 6 personcard person 7 } 8 } 9 } 10 }` the graphql comes from react relay and implements the query as a string it is important to understand edges and node connection the query above is consuming a node connection of people from the back4app server every time you create a new class, it will be followed by a node connection variables when necessary, the query renderer will consume variables a good example when the application requests a query for a person by id as this is not the case right now, let’s pass by null on the variables props populating the person card this query will return a list of people the query renderer ensures that the data will be available to render if it doesn’t, shoot an error the props responsible for this is the render populate the render props with the following code 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 }} replace the commented todo for a javascript map for rendering a person card for each result from the list as said, the query renderer takes responsibility for making the data available only when it is ready until then, a loading message will be displayed if an error occurs, it will be displayed on the screen preventing an unexpected application crash by last, let improves the render of person replacing the map by a new function put it before the query renderer 1 const renderpersons = (people) => { 2 return people edges map(({node}) => \<personcard person={node} />); 3 }; and the final result should look like 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 making your first query now it is time to fetch the person using the personrenderer if everything is ok, your application now has two new components personrenderer and personcard before starting the application, the relay needs the relay compiler to run and generate the component types for this, run into your terminal yarn relay on app js add the followng code 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; the code of app js comes originally from create react native app it added a view with a style to center the content on the screen with a margin of 10px from the top inside of it has a text with a label to give some context for the print and the personrenderer to show the list of person you need to get the following result rendering in our back4app react native application, we import the personrenderer directly into the app js app js as the personrenderer is a root component and has its queryrenderer, the person must be displayed without any error 6 typing the components this step makes sense for an application that works with typescript if your application doesn’t use typescript, go ahead one of the powers of the relay compiler is to generate the types from each data component let’s type the personrenderer and personcard to make the application more powerful typing personrenderer type the renderperson function arg people people into personrenderer 1 const renderpersons = (people personrendererquery\['response']\['people']) => { 2 return people edges map(({node}) => \<personcard person={node} />); 3 }; import the personrendererquery personrendererquery type from generated generated folder created inside of the same folder of the personrenderer typing personcard go ahead to personcard, create a new type object and name it personcardprops 1 type personcardprops = {}; import the personcard person personcard person type from generated generated folders 1 import {personcard person} from ' / generated /personcard person graphql'; add the person inside the type personcardprops 1 type personcardprops = { 2 person personcard person; 3 }; on props arguments from personcard, type the component with the personcardprops personcardprops 1 const personcard = ({person} personcardprops) => { } the final result of both components should look like 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 }); conclusion the final result of queryrenderer demonstrated how the application can be abstracted the application can display the person inside of the query renderer as the personcard has more components, it doesn’t change the way the query renderer was built the personrenderer was built to show how a query can be done in easy steps, combined with the power of the back4app server in the next guide, you will learn how to retrieve a specific person object and show their attributes