<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ apollo client - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ apollo client - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 25 May 2026 22:38:29 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/apollo-client/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ GraphQL for Front End Developers ]]>
                </title>
                <description>
                    <![CDATA[ By Gaurav Tewari If you are a front end developer who is new to the world of GraphQL and you're thinking about getting started with it, this article is for you.  In this article, we will explore GraphQL basics and kick start our journey with it by bu... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/graphql-for-front-end-developers/</link>
                <guid isPermaLink="false">66d45edb4a7504b7409c33d1</guid>
                
                    <category>
                        <![CDATA[ apollo client ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 19 Oct 2021 17:19:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/10/Getting-Started-in-GraphQL-for-front-end-developers--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Gaurav Tewari</p>
<p>If you are a front end developer who is new to the world of GraphQL and you're thinking about getting started with it, this article is for you. </p>
<p>In this article, we will explore GraphQL basics and kick start our journey with it by building a simple project. </p>
<h2 id="heading-what-is-graphql">What is GraphQL?</h2>
<p>GraphQL is a query language that lets apps fetch data from the API's. But what it does differently is that is allows clients to specify how to structure the data when it is returned by the server. This means that the client only asks for the data it needs and even specifies the format in which it needs the data. </p>
<p>But what problem does it actually solve?</p>
<p>It solves the problem of under fetching and over fetching. Ok but what's that? Well, let me tell you.</p>
<p>Let's say you only need to display a userName, userImage, and Name in your profile page on your website or app. But when you request the data you are getting lots of other information about the user which you don't need. </p>
<p>This is called <strong>over fetching</strong> – you are fetching a lot of data, even the data you don't need. On the other hand, <strong>under fetching</strong> is when we get less data than you need. So neither one is great. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/sketch1634455883941.png" alt="Image" width="600" height="400" loading="lazy">
<em>under Fetching example</em></p>
<p>You might think ok, that's not a problem at all. Well, it's not a big problem in small scale applications. But what about in large scale applications that have millions of users? In those cases, over fetching and under fetching waste a lot of resources, which is where GraphQL comes in. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/d666aceb-62c2-4482-9c42-cbd12d2d42b6.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h1 id="heading-how-to-get-started-with-graphql">How to Get Started With GraphQL</h1>
<p>Here we'll cover some key concepts you need to know before getting started with graphQL </p>
<h3 id="heading-graphql-playground">GraphQL PlayGround</h3>
<p>GraphQL playground is an interactive, Graphical IDE for GraphQL where you can visually explore the server. In it you can test various GraphQL queries and see their results in front of your eyes. </p>
<p><a target="_blank" href="https://graphqlpokemon.favware.tech/">Here is a link to GraphQL playground you can check out.</a></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/Screenshot-2021-10-17-at-1.57.04-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>GraphQL playground</em></p>
<p>If you click on the play button it will run the query. </p>
<h3 id="heading-how-do-you-request-write-or-post-data-in-graphql">How do you request, write, or post data in GraphQL?</h3>
<p>You request data through a query in GraphQL. And to write or post data, you use mutations. </p>
<p>Whenever we perform a GraphQL operation, we specify whether it is a mutation or a query. Then we name that operation, and this is the basic way of performing a GraphQL query. </p>
<pre><code>
GraphQLOperatoinType Name {
 ....
 ........
 .....
 ...
}
</code></pre><p>To make a simple query, the syntax would be:</p>
<pre><code>query getData {
...
}
</code></pre><p>Similarly, to add a mutation we would write <code>mutation</code> in place of <code>query</code>.</p>
<p>Now since we know the basics, let's get our hands dirty. We will be using the <a target="_blank" href="https://studio.apollographql.com/sandbox/explorer?endpoint=https%3A%2F%2Fgraphql.anilist.co&amp;explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4TADpIAR4AKAhgOYJ474F6JgCWxluNNAzvSggKoBOANi1Z4UnfhSrCayUv3psAFkKlJiogG4JlNAL7aCYBGyi96AB1EQk2vdVs6QAGhDrip4gCNxbDFmy9cBx0gA&amp;_gl=1*1sgkza2*_ga*MTg1Mzg5MTM4Ni4xNjM0MjExNTMz*_ga_0BGG5V2W2K*MTYzNDM2NTQxMS43LjEuMTYzNDM2ODk5Ny4w">Anilist API</a> to get a list of  anime shows. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/Screenshot-2021-10-17-at-2.25.53-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Apollo studio</em></p>
<h3 id="heading-how-to-use-apollo-studio">How to Use Apollo Studio</h3>
<p>You've gotten a small taste of GraphQL playground, but there's something even more awesome called Apollo Studio. It makes life easier as a front end developer. In it, you just need select the fields you want and it writes a query for you. </p>
<p>From the left hand side select the fields you want in your Query, and that's it. GraphQL will automatically create a query for you. Now you've made the query, but how do you use it in your application? </p>
<p>Well let's get started building a simple Anime App with it.</p>
<p>We'll use React in this project, but you can choose any framework or library you'd like.</p>
<p>Firstly, create a new project in React:</p>
<pre><code>npx create-react-app graphql-example
</code></pre><p>Now once the project is created go inside the project directory and install the Apollo client.</p>
<pre><code>npm install graphql @apollo/client
</code></pre><p>Once it's done, go the src/index.js and import ApolloClient, InMemoryCache, and ApolloProvider:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> {ApolloClient, InMemoryCache, ApolloProvider} <span class="hljs-keyword">from</span> <span class="hljs-string">'@apollo/client'</span>;
</code></pre>
<p>Apollo Client is a class which represents the Apollo client itself, and we use it to create a new client instance.</p>
<p>Here we need to provide a couple of things to it. One is the URI where we specify the URL of our GraphQL server. Also every instance of our Apollo client needs a cache so it can reduce the network requests and can make our app much faster.</p>
<p>This is what our new client look like:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> ApolloClient({
  <span class="hljs-attr">uri</span> : <span class="hljs-string">'https://graphql.anilist.co/'</span>,
  <span class="hljs-attr">cache</span>: <span class="hljs-keyword">new</span> InMemoryCache(),
})
</code></pre>
<p>Now we need to make this client available throughout our component tree so we wrap our app's top level component in ApolloProvider. </p>
<p>Now we are done with the initial setup, so it's time to make a query and ask our API for the data – but how do we do that?</p>
<p>We can do so using the useQuery hook. But before that we need to define a query, which we can do using the GQL (we need to wrap our query inside it). So now, import these two from the Apollo client:</p>
<pre><code><span class="hljs-keyword">import</span> {useQuery, gql} <span class="hljs-keyword">from</span> <span class="hljs-string">'@apollo/client'</span>;
</code></pre><p>After importing them, we'll wrap our query inside GQL:</p>
<pre><code> <span class="hljs-keyword">const</span> AnimeList = gql<span class="hljs-string">`
 query Query {
  Page {
    media {
      siteUrl
      title {
        english
        native
      }
      description
      coverImage {
        medium
      }
      bannerImage
      volumes
      episodes
    }
  }
}
}



`</span>;
</code></pre><p>At this point you must be wondering if the query part is done, how do we get data from it now?</p>
<p>That's where the useQuery hook comes handy. It returns <code>loading</code>, <code>error</code>, and <code>data</code> properties we can use.</p>
<pre><code>  <span class="hljs-keyword">const</span> {loading, error, data} = useQuery(AnimeList);
</code></pre><p>For now we can just display the data to check whether our app works or not:</p>
<pre><code><span class="hljs-keyword">if</span>(loading) <span class="hljs-keyword">return</span>(<span class="xml"><span class="hljs-tag">&lt;&gt;</span> Loading<span class="hljs-tag">&lt;/&gt;</span></span>);
  <span class="hljs-keyword">if</span>(error) <span class="hljs-keyword">return</span>(<span class="xml"><span class="hljs-tag">&lt;&gt;</span>{JSON.stringify(error)}<span class="hljs-tag">&lt;/&gt;</span></span>)
  <span class="hljs-keyword">return</span> (
   <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
   {JSON.stringify(data)}
   <span class="hljs-tag">&lt;/&gt;</span></span>);
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2021/10/Screenshot-2021-10-16-at-5.42.06-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Well it works for now – time to style it.</p>
<p>Maybe we can use object chaining to implement that nicely:</p>
<pre><code> &lt;div className=<span class="hljs-string">"container"</span>&gt; 
     <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span> 🐈 Anime List <span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>
     <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">hr</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"80%"</span> /&gt;</span></span>
   {data?.Page?.media.map(<span class="hljs-function"><span class="hljs-params">anime</span> =&gt;</span> (
     <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"card"</span> &gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">img</span>    <span class="hljs-attr">src</span>=<span class="hljs-string">{anime.coverImage.medium}/</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span> 
         <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>{anime.title.english} <span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
           <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"episodes"</span> &gt;</span>Episodes  <span class="hljs-tag">&lt;<span class="hljs-name">b</span>&gt;</span>{anime.episodes} <span class="hljs-tag">&lt;/<span class="hljs-name">b</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span>  <span class="hljs-attr">dangerouslySetInnerHTML</span>=<span class="hljs-string">{{__html:</span> <span class="hljs-attr">anime.description</span>}} &gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> 
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> 
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">hr</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"75%"</span>/&gt;</span>
 <span class="hljs-tag">&lt;/&gt;</span></span>
   ))}
   &lt;div className=<span class="hljs-string">"buttonContainer"</span>&gt;
    { page != <span class="hljs-number">1</span> &amp;&amp; <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span> Previous Page<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span> } 
     &lt;div className=<span class="hljs-string">"pageText"</span>&gt; {page}&lt;/div&gt;
     <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{NextPage}</span>&gt;</span>  Next Page <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span> 
   &lt;/div&gt;
   &lt;/div&gt;);
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2021/10/Screenshot-2021-10-17-at-6.02.20-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>minimistic styled app</em></p>
<p>You can check out this <a target="_blank" href="https://github.com/tewarig/graphql-Example/blob/7df5c7c199878484e36742287e513d5a249b466b/src/App.css">GitHub repo for the CSS file</a>.</p>
<p>Now we are able to get a list of anime films from the API. So what do we need to get them from the next page of the app? </p>
<p>We need to pass a variable that has a page name into the query. That's where variables in GraphQL come into the picture. </p>
<p>First, go to Apollo Studio and click on the arguments on the left hand side (first go to root &gt; query &gt;page and you'll see it):</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/Screenshot-2021-10-17-at-6.06.58-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Click on page and it'll add an argument to your query.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/Screenshot-2021-10-17-at-6.09.46-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Also notice that in the variable page in the variables section, you can change its value and play around a little bit with it. But the data will only change according to the page.</p>
<p>Now we need to pass this variable into the query – and then we'll be able to display next page's anime in our app.</p>
<p>For that we'll be using the useState hook to keep a track of our current page's value. We also need to make a function to increment and decrement that as well.</p>
<pre><code>  <span class="hljs-keyword">const</span> [page, setPage] = useState(<span class="hljs-number">1</span>);
  <span class="hljs-comment">//this is how we would be passing the page in the query.</span>
  <span class="hljs-keyword">const</span> {loading, error, data} = useQuery(AnimeList , {  <span class="hljs-attr">variables</span>: { <span class="hljs-string">"page"</span> : page } });

<span class="hljs-keyword">const</span> NextPage = <span class="hljs-function">() =&gt;</span> {
    setPage(page+<span class="hljs-number">1</span>);
  }
  <span class="hljs-keyword">const</span> PreviousPage = <span class="hljs-function">() =&gt;</span> {
    setPage(page - <span class="hljs-number">1</span>);
  }

   &lt;div className=<span class="hljs-string">"buttonContainer"</span>&gt;
    { page != <span class="hljs-number">1</span> &amp;&amp; <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{PreviousPage}</span>&gt;</span> Previous Page<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span> } 
     &lt;div className=<span class="hljs-string">"pageText"</span>&gt; {page}&lt;/div&gt;
     <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{NextPage}</span>&gt;</span>  Next Page <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span> 
   &lt;/div&gt;
</code></pre><p>And now we're done building our simple app with GraphQL. If you want to check out the codebase, <a target="_blank" href="https://github.com/tewarig/graphql-Example">here is the link</a>. </p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>In this article, we have covered some of the basic concepts to help you get started using GraphQL. Thank you for reading, and happy coding. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Fetch Data in React from a GraphQL API ]]>
                </title>
                <description>
                    <![CDATA[ Let's go through the five best ways that you can fetch data with React from a GraphQL API. While there are a couple of popular libraries which are made to interact with GraphQL APIs from a React application, there are many different ways to fetch dat... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/5-ways-to-fetch-data-react-graphql/</link>
                <guid isPermaLink="false">66d0374accf811d3117aeedb</guid>
                
                    <category>
                        <![CDATA[ apollo client ]]>
                    </category>
                
                    <category>
                        <![CDATA[ axios ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Reed ]]>
                </dc:creator>
                <pubDate>Mon, 03 May 2021 17:20:56 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/05/5-ways-to-fetch-data-in-react-with-graphql-2.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Let's go through the five best ways that you can fetch data with React from a GraphQL API.</p>
<p>While there are a couple of popular libraries which are made to interact with GraphQL APIs from a React application, there are many different ways to fetch data with GraphQL.</p>
<p>I've included code samples that show you how to fetch or "query" data in the shortest code possible and how to get up and running with each of these different methods of connecting React with GraphQL. </p>
<h2 id="heading-getting-started">Getting Started</h2>
<p>In these examples, we'll be using the SpaceX GraphQL API to fetch and display the past 10 missions that SpaceX has made. </p>
<p>Feel free to use the code below if you are attempting to connect your React app with a GraphQL API. In these examples, we're going to go from the most advanced GraphQL client library for React to the simplest approach to querying a GraphQL endpoint. </p>
<h2 id="heading-1-apollo-client">1. Apollo Client</h2>
<p>The most popular and comprehensive GraphQL library is Apollo Client. </p>
<p>Not only can you use it to fetch remote data with GraphQL, which we're doing here, but it allows us to manage data locally, both through an internal cache as well as an entire state management API. </p>
<p>To get started with Apollo Client, you need to install both the main Apollo Client dependency, as well as GraphQL:</p>
<pre><code class="lang-bash">npm install @apollo/client graphql
</code></pre>
<p>The idea behind the Apollo Client is that it will be used across your entire application. To do this, you'll use a special Apollo Provider component to pass a created Apollo client down your entire component tree.</p>
<p>When you create your Apollo Client, you need to specify a <code>uri</code> value, namely a GraphQL endpoint. Additionally, you need to specify a cache. </p>
<p>Apollo Client comes with its own in memory cache, which is used to cache or locally store and manage your queries and their related data:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">"react-dom"</span>;
<span class="hljs-keyword">import</span> { ApolloProvider, ApolloClient, InMemoryCache } <span class="hljs-keyword">from</span> <span class="hljs-string">"@apollo/client"</span>;

<span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">"./App"</span>;

<span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> ApolloClient({
  <span class="hljs-attr">uri</span>: <span class="hljs-string">"https://api.spacex.land/graphql/"</span>,
  <span class="hljs-attr">cache</span>: <span class="hljs-keyword">new</span> InMemoryCache()
});

<span class="hljs-keyword">const</span> rootElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"root"</span>);
ReactDOM.render(
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ApolloProvider</span> <span class="hljs-attr">client</span>=<span class="hljs-string">{client}</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">ApolloProvider</span>&gt;</span></span>,
  rootElement
);
</code></pre>
<p>Once you've set up the Provider and client within your App component, you can use all of the different React hooks that Apollo Client gives you for all the different GraphQL operations. These include queries, mutations, and subscriptions. You can even use the created Apollo Client directly using a custom hook called <code>useApolloClient</code>. </p>
<p>Since you're just querying data here, you will use the <code>useQuery</code> hook. </p>
<p>You will include a GraphQL query as its first argument to write your query. You'll use the function <code>gql</code>, which does a number of things, such as giving you editor syntax highlighting and the auto formatting functionality if you use the tool Prettier for your project. </p>
<p>Once you execute this query, you get back the values <code>data</code>, <code>loading</code>, and <code>error</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { useQuery, gql } <span class="hljs-keyword">from</span> <span class="hljs-string">"@apollo/client"</span>;

<span class="hljs-keyword">const</span> FILMS_QUERY = gql<span class="hljs-string">`
  {
    launchesPast(limit: 10) {
      id
      mission_name
    }
  }
`</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { data, loading, error } = useQuery(FILMS_QUERY);

  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="hljs-string">"Loading..."</span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">pre</span>&gt;</span>{error.message}<span class="hljs-tag">&lt;/<span class="hljs-name">pre</span>&gt;</span></span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>SpaceX Launches<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
        {data.launchesPast.map((launch) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{launch.id}</span>&gt;</span>{launch.mission_name}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        ))}
      <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p> Before you display your data, your missions, you want to handle the loading state. When you are in a loading state, you are fetching the query from a remote endpoint. </p>
<p>You also want to handle any errors that occur. You can simulate an error by making a syntax error in your query, such as querying for a field that doesn't exist. To handle that error, you can conveniently return and display a message from <code>error.message</code>.</p>
<h2 id="heading-2-urql">2. Urql</h2>
<p>Another fully-featured library that connects React apps with GraphQL APIs is urql.</p>
<p>It attempts to give you many of the features and syntax Apollo has while being a little bit smaller in size and requiring less setup code. It gives you caching capabilities if you choose, but it does not include an integrated state management library like Apollo does.</p>
<p>To use urql as your GraphQL client library, you'll need to install the packages urql and GraphQL. </p>
<pre><code class="lang-bash">npm install urql graphql
</code></pre>
<p>Just like Apollo, you'll want to use the dedicated Provider component, and create a client with your GraphQL endpoint. Note that you do not need to specify a cache out of the box.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">"react-dom"</span>;
<span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">"./App"</span>;
<span class="hljs-keyword">import</span> { createClient, Provider } <span class="hljs-keyword">from</span> <span class="hljs-string">'urql'</span>;

<span class="hljs-keyword">const</span> client = createClient({
  <span class="hljs-attr">url</span>: <span class="hljs-string">'https://api.spacex.land/graphql/'</span>,
});

<span class="hljs-keyword">const</span> rootElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"root"</span>);
ReactDOM.render(
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Provider</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{client}</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">Provider</span>&gt;</span></span>,
  rootElement
);
</code></pre>
<p>Very similar to Apollo, urql gives you custom hooks that handle all the standard GraphQL operations, and therefore have similar names.</p>
<p>Again, you can use the <code>useQuery</code> hook from the urql package. Although instead of needing the function <code>gql</code>, you can drop it and just use a template literal to write your query. </p>
<p>When calling <code>useQuery</code>, you get back an array which you can destructure as an array instead of as an object. The first element in this array is an object, called <code>result</code>, which gives you a number of properties that you can destructure: <code>data</code>, <code>fetching</code>, and <code>error</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { useQuery } <span class="hljs-keyword">from</span> <span class="hljs-string">'urql'</span>;

<span class="hljs-keyword">const</span> FILMS_QUERY = <span class="hljs-string">`
  {
    launchesPast(limit: 10) {
      id
      mission_name
    }
  }
`</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [result] = useQuery({
    <span class="hljs-attr">query</span>: FILMS_QUERY,
  });

  <span class="hljs-keyword">const</span> { data, fetching, error } = result;

  <span class="hljs-keyword">if</span> (fetching) <span class="hljs-keyword">return</span> <span class="hljs-string">"Loading..."</span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">pre</span>&gt;</span>{error.message}<span class="hljs-tag">&lt;/<span class="hljs-name">pre</span>&gt;</span></span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>SpaceX Launches<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
        {data.launchesPast.map((launch) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{launch.id}</span>&gt;</span>{launch.mission_name}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        ))}
      <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>In an identical fashion to displaying the data that you fetch with Apollo, you can handle both your error and loading states while you're fetching your remote data.</p>
<h2 id="heading-3-react-query-graphql-request">3. React Query + GraphQL Request</h2>
<p>It's important to note at this point that you don't need a sophisticated, heavyweight GraphQL client library like urql or Apollo to interact with your GraphQL API, as we will see later. </p>
<p>Libraries like Apollo and urql were created not only to help you perform all the standard GraphQL operations, but to better manage the server state in your React client through a number of additional tools. All this along with the fact that they come with custom hooks that make managing repetitive tasks like handling loading, error, and other related states simple. </p>
<p>With that in mind, let's take a look at how you can use a very pared-down GraphQL library for your data fetching and combine that with a better means of managing and caching that server state that you're bringing into your application. You can fetch data very simply with the help of the package <code>graphql-request</code>. </p>
<p>GraphQL Request is a library that doesn't require you to set up a client or a Provider component. It is essentially a function that just accepts an endpoint and a query. Very similar to an HTTP client, you just have to pass in those two values and you get back your data. </p>
<p>Now if you want to manage that state across your app, you can use a great library normally used for interacting with Rest APIs – but it's equally helpful for GraphQL APIs – and that is React Query. It gives you some very similarly named React Hooks, <code>useQuery</code> and <code>useMutation</code>, that perform identical tasks to what the Apollo and urql hooks perform. </p>
<p>React Query also gives you a bunch of tools for managing state, along with an integrated Dev Tools component that allows you to see what's being stored in React Query's built-in cache. </p>
<blockquote>
<p>By pairing your very basic GraphQL client, GraphQL request, with React Query you get all the power of a library like urql or Apollo. </p>
</blockquote>
<p>To get started with this pairing, you just need to install React Query and GraphQL Request: </p>
<pre><code class="lang-bash">npm install react-query graphql-request
</code></pre>
<p>You use React Query's Provider component and create a query client where you can set some default data fetching settings if you like. Then within your app component itself, or any child components of <code>App</code>, you can use the <code>useQuery</code> hook. </p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">"react-dom"</span>;
<span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">"./App"</span>;
<span class="hljs-keyword">import</span> { QueryClient, QueryClientProvider } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-query"</span>;

<span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> QueryClient();

<span class="hljs-keyword">const</span> rootElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"root"</span>);
ReactDOM.render(
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">QueryClientProvider</span> <span class="hljs-attr">client</span>=<span class="hljs-string">{client}</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">QueryClientProvider</span>&gt;</span></span>,
  rootElement
);
</code></pre>
<p>To store the result of your operation in the React Query cache, you just need to give it a key value as the first argument to serve as an identifier. This allows you to very easily reference and pull data from the cache, as well as to refetch or invalidate a given query to fetch updated data.</p>
<p>Since you're fetching launch data, let's call this query "launches". </p>
<p>Once again, this hook will return the result of making that request. For the second argument to <code>useQuery</code>, you need to specify how to fetch that data and React Query will take care of resolving the promise that GraphQL request returns. </p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { request, gql } <span class="hljs-keyword">from</span> <span class="hljs-string">"graphql-request"</span>;
<span class="hljs-keyword">import</span> { useQuery } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-query"</span>;

<span class="hljs-keyword">const</span> endpoint = <span class="hljs-string">"https://api.spacex.land/graphql/"</span>;
<span class="hljs-keyword">const</span> FILMS_QUERY = gql<span class="hljs-string">`
  {
    launchesPast(limit: 10) {
      id
      mission_name
    }
  }
`</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { data, isLoading, error } = useQuery(<span class="hljs-string">"launches"</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> request(endpoint, FILMS_QUERY);
  });

  <span class="hljs-keyword">if</span> (isLoading) <span class="hljs-keyword">return</span> <span class="hljs-string">"Loading..."</span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">pre</span>&gt;</span>{error.message}<span class="hljs-tag">&lt;/<span class="hljs-name">pre</span>&gt;</span></span>;

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>SpaceX Launches<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
        {data.launchesPast.map((launch) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{launch.id}</span>&gt;</span>{launch.mission_name}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        ))}
      <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>Similar to Apollo, you get back an object that you can destructure to get the values for the data, as well as whether or not you're in the loading state, and the error state.</p>
<h2 id="heading-4-react-query-axios">4. React Query + Axios</h2>
<p>You can use even simpler HTTP client libraries that have no relationship to GraphQL to fetch your data. </p>
<p>In this case, you can use the popular library axios. Once again you can pair it with React Query to get all the special hooks and state management.</p>
<pre><code class="lang-bash">npm install react-query axios
</code></pre>
<p>Using an HTTP client like Axios to perform a query from a GraphQL API requires performing a POST request to your API endpoint. For the data that you send along in the request, you will provide an object with a property called <code>query</code>, which will be set to your films query. </p>
<p>With axios, you're going to need to include a little bit more information about how to resolve this promise and get back your data. You need to tell React Query where the data is so it can be put on the <code>data</code> property that <code>useQuery</code> returns.</p>
<p>In particular, you get the data back on the data property of <code>response.data</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;
<span class="hljs-keyword">import</span> { useQuery } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-query"</span>;

<span class="hljs-keyword">const</span> endpoint = <span class="hljs-string">"https://api.spacex.land/graphql/"</span>;
<span class="hljs-keyword">const</span> FILMS_QUERY = <span class="hljs-string">`
  {
    launchesPast(limit: 10) {
      id
      mission_name
    }
  }
`</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { data, isLoading, error } = useQuery(<span class="hljs-string">"launches"</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> axios({
      <span class="hljs-attr">url</span>: endpoint,
      <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
      <span class="hljs-attr">data</span>: {
        <span class="hljs-attr">query</span>: FILMS_QUERY
      }
    }).then(<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> response.data.data);
  });

  <span class="hljs-keyword">if</span> (isLoading) <span class="hljs-keyword">return</span> <span class="hljs-string">"Loading..."</span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">pre</span>&gt;</span>{error.message}<span class="hljs-tag">&lt;/<span class="hljs-name">pre</span>&gt;</span></span>;

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>SpaceX Launches<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
        {data.launchesPast.map((launch) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{launch.id}</span>&gt;</span>{launch.mission_name}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        ))}
      <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<h2 id="heading-5-react-query-fetch-api">5. React Query + Fetch API</h2>
<p>The easiest way of all these different approaches to fetch data is to just use React query plus the fetch API. </p>
<p>Since the fetch API is included in all modern browsers, you do not need to install a third-party library – you only need to install <code>react-query</code> within your application. </p>
<pre><code class="lang-bash">npm install react-query
</code></pre>
<p>Once you have the React Query client provided to the entire app, you can just swap out your axios code with fetch. </p>
<p>What's a little bit different is that you need to specify a header that includes the content type of the data that you want back from your request. In this case, it is JSON data. </p>
<p>You also need to stringify the object that you're sending as your payload with a query property that is set to your films query:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;
<span class="hljs-keyword">import</span> { useQuery } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-query"</span>;

<span class="hljs-keyword">const</span> endpoint = <span class="hljs-string">"https://api.spacex.land/graphql/"</span>;
<span class="hljs-keyword">const</span> FILMS_QUERY = <span class="hljs-string">`
  {
    launchesPast(limit: 10) {
      id
      mission_name
    }
  }
`</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { data, isLoading, error } = useQuery(<span class="hljs-string">"launches"</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> fetch(endpoint, {
      <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
      <span class="hljs-attr">headers</span>: { <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span> },
      <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({ <span class="hljs-attr">query</span>: FILMS_QUERY })
    })
      .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
        <span class="hljs-keyword">if</span> (response.status &gt;= <span class="hljs-number">400</span>) {
          <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Error fetching data"</span>);
        } <span class="hljs-keyword">else</span> {
          <span class="hljs-keyword">return</span> response.json();
        }
      })
      .then(<span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> data.data);
  });

  <span class="hljs-keyword">if</span> (isLoading) <span class="hljs-keyword">return</span> <span class="hljs-string">"Loading..."</span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">pre</span>&gt;</span>{error.message}<span class="hljs-tag">&lt;/<span class="hljs-name">pre</span>&gt;</span></span>;

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>SpaceX Launches<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
        {data.launchesPast.map((launch) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{launch.id}</span>&gt;</span>{launch.mission_name}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        ))}
      <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>One benefit of using axios over fetch is that it automatically handles errors for you. With fetch, as you can see in the code above, you need to check for a certain status code, in particular a status code above 400. </p>
<p>This means that your request resolves to an error. If that's the case, you need to manually throw an error, which will be caught by your <code>useQuery</code> hook. Otherwise, if it's a 200 or 300 range response, meaning the request was successful, simply return the JSON data and display it.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This article was dedicated to showing you a number of different approaches to effectively fetching data from a GraphQL API with React.  </p>
<p>From these options, hopefully you can evaluate which is most appropriate for you and your applications. And now you have some helpful code that will enable you to start using these tools and libraries much faster.</p>
<h2 id="heading-become-a-professional-react-developer">Become a Professional React Developer</h2>
<p>React is hard. You shouldn't have to figure it out yourself.</p>
<p>I've put everything I know about React into a single course, to help you reach your goals in record time:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><strong>Introducing: The React Bootcamp</strong></a></p>
<p><strong>It’s the one course I wish I had when I started learning React.</strong></p>
<p>Click below to try the React Bootcamp for yourself:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><img src="https://reedbarger.nyc3.digitaloceanspaces.com/reactbootcamp/react-bootcamp-cta-alt.png" alt="Click to join the React Bootcamp" width="600" height="400" loading="lazy"></a>
<em>Click to get started</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The React + Apollo Tutorial for 2020 (Real-World Examples) ]]>
                </title>
                <description>
                    <![CDATA[ If you want to build apps with React and GraphQL, Apollo is the library you should use. I've put together a comprehensive cheatsheet that goes through all of the core concepts in the Apollo library, showing you how to use it with React from front to ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/react-apollo-client-2020-tutorial/</link>
                <guid isPermaLink="false">66d037b131fbfb6c3390f209</guid>
                
                    <category>
                        <![CDATA[ 2020 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Apollo GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ apollo client ]]>
                    </category>
                
                    <category>
                        <![CDATA[ cheatsheet ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Tutorial ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Reed ]]>
                </dc:creator>
                <pubDate>Sat, 04 Jul 2020 13:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/07/React---Apollo-2020-Cheatsheet.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you want to build apps with React and GraphQL, Apollo is the library you should use.</p>
<p>I've put together a comprehensive cheatsheet that goes through all of the core concepts in the Apollo library, showing you how to use it with React from front to back.</p>
<h3 id="heading-want-your-own-copy">Want Your Own Copy?</h3>
<p>You can grab the PDF cheatsheet <strong><a target="_blank" href="https://reedbarger.com/resources/react-apollo-2020/">right here</a></strong> (it takes 5 seconds).</p>
<p>Here are some quick wins from grabbing the downloadable version:</p>
<ul>
<li>✓ Quick reference to review however and whenever</li>
<li>✓ Tons of useful code snippets based off of real-world projects</li>
<li>✓ Read this guide offline, wherever you like. On the train, at your desk, standing in line — anywhere.</li>
</ul>
<h3 id="heading-prefer-video-lessons">Prefer Video Lessons?</h3>
<p>A great deal of this cheatsheet is based off of the app built in the React + GraphQL 2020 Crash Course. </p>
<p>If you want some more hands-on video lessons, plus see how to build apps with React, GraphQL and Apollo, you can watch the course <a target="_blank" href="https://bit.ly/2020-react-graphql">right here</a>.</p>
<blockquote>
<p>Note: This cheatsheet does assume familiarity with React and GraphQL. If you need a quick refresher on GraphQL and how to write it, a great resource is the <a target="_blank" href="https://graphql.org/learn/">official GraphQL website</a>.</p>
</blockquote>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<h3 id="heading-getting-started">Getting Started</h3>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-apollo-and-why-do-we-need-it">What is Apollo and why do we need it?</a></li>
<li><a class="post-section-overview" href="#heading-apollo-client-basic-setup">Apollo Client setup</a></li>
<li><a class="post-section-overview" href="#heading-creating-a-new-apollo-client-basic-setup">Creating a new Apollo Client</a></li>
<li><a class="post-section-overview" href="#heading-providing-the-client-to-react-components">Providing the client to React components</a></li>
<li><a class="post-section-overview" href="#heading-using-the-client-directly">Using the client directly</a></li>
<li><a class="post-section-overview" href="#heading-writing-graphql-operations-in-js-files-gql">Writing GraphQL in .js files with gql</a></li>
</ul>
<h3 id="heading-core-apollo-react-hooks">Core Apollo React Hooks</h3>
<ul>
<li><a class="post-section-overview" href="#heading-usequery-hook">useQuery Hook</a></li>
<li><a class="post-section-overview" href="#heading-uselazyquery-hook">useLazyQuery Hook</a></li>
<li><a class="post-section-overview" href="#heading-usemutation-hook">useMutation Hook</a></li>
<li><a class="post-section-overview" href="#heading-usesubscription-hook">useSubscription Hook</a></li>
</ul>
<h3 id="heading-essential-recipes">Essential Recipes</h3>
<ul>
<li><a class="post-section-overview" href="#heading-manually-setting-the-fetch-policy">Manually setting the fetch policy</a></li>
<li><a class="post-section-overview" href="#heading-updating-the-cache-upon-a-mutation">Updating the cache upon a mutation</a></li>
<li><a class="post-section-overview" href="#heading-refetching-queries-with-usequery">Refetching queries with useQuery</a></li>
<li><a class="post-section-overview" href="#heading-refetching-queries-with-usemutation">Refetching queries with useMutation</a></li>
<li><a class="post-section-overview" href="#heading-using-the-client-with-useapolloclient">Accessing the client with useApolloClient</a></li>
</ul>
<h3 id="heading-what-is-apollo-and-why-do-we-need-it">What is Apollo and why do we need it?</h3>
<p>Apollo is a library that brings together two incredibly useful technologies used to build web and mobile apps: React and GraphQL. </p>
<p>React was made for creating great user experiences with JavaScript. GraphQL is a very straightforward and declarative new language to more easily and efficiently fetch and change data, whether it is from a database or even from static files. </p>
<p>Apollo is the glue that binds these two tools together. Plus it makes working with React and GraphQL a lot easier by giving us a lot of custom React hooks and features that enable us to both write GraphQL operations and execute them with JavaScript code. </p>
<p>We'll cover these features in-depth throughout the course of this guide.</p>
<h3 id="heading-apollo-client-basic-setup">Apollo Client basic setup</h3>
<p>If you are starting a project with a React template like Create React App, you will need to install the following as your base dependencies to get up and running with Apollo Client:</p>
<pre><code class="lang-bash">// with npm:
npm i @apollo/react-hooks apollo-boost graphql

// with yarn:
yarn add @apollo/react-hooks apollo-boost graphql
</code></pre>
<p><code>@apollo/react-hooks</code> gives us React hooks that make performing our operations and working with Apollo client better</p>
<p><code>apollo-boost</code> helps us set up the client along with parse our GraphQL operations</p>
<p><code>graphql</code> also takes care of parsing the GraphQL operations (along with gql)</p>
<h3 id="heading-apollo-client-subscriptions-setup">Apollo Client + subscriptions setup</h3>
<p>To use all manner of GraphQL operations (queries, mutations, and subscriptions), we need to install more specific dependencies as compared to just <code>apollo-boost</code>:</p>
<pre><code class="lang-bash">// with npm:
npm i @apollo/react-hooks apollo-client graphql graphql-tag apollo-cache-inmemory apollo-link-ws

// with yarn:
yarn add @apollo/react-hooks apollo-client graphql graphql-tag apollo-cache-inmemory apollo-link-ws
</code></pre>
<p><code>apollo-client</code> gives us the client directly, instead of from <code>apollo-boost</code></p>
<p><code>graphql-tag</code> is integrated into <code>apollo-boost</code>, but not included in <code>apollo-client</code></p>
<p><code>apollo-cache-inmemory</code> is needed to setup our own cache (which <code>apollo-boost</code>, in comparison, does automatically)</p>
<p><code>apollo-link-ws</code> is needed for communicating over websockets, which subscriptions require</p>
<h3 id="heading-creating-a-new-apollo-client-basic-setup">Creating a new Apollo Client (basic setup)</h3>
<p>The most straightforward setup for creating an Apollo client is by instantiating a new client and providing just the <code>uri</code> property, which will be your GraphQL endpoint:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> ApolloClient <span class="hljs-keyword">from</span> <span class="hljs-string">"apollo-boost"</span>;

<span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> ApolloClient({
  <span class="hljs-attr">uri</span>: <span class="hljs-string">"https://your-graphql-endpoint.com/api/graphql"</span>,
});
</code></pre>
<p><code>apollo-boost</code> was developed in order to make doing things like creating an Apollo Client as easy as possible. What it lacks for the time being, however, is support for GraphQL subscriptions over a websocket connection. </p>
<p>By default, it performs the operations over an http connection (as you can see through our provided uri above).</p>
<p>In short, use <code>apollo-boost</code> to create your client if you only need to execute queries and mutations in your app. </p>
<p>It setups an in-memory cache by default, which is helpful for storing our app data locally. We can read from and write to our cache to prevent having to execute our queries after our data is updated. We'll cover how to do that a bit later.</p>
<h3 id="heading-creating-a-new-apollo-client-subscriptions-setup">Creating a new Apollo Client (+ subscriptions setup)</h3>
<p>Subscriptions are useful for more easily displaying the result of data changes (through mutations) in our app. </p>
<p>Generally speaking, we use subscriptions as an improved kind of query. Subscriptions use a websocket connection to 'subscribe' to updates and data, enabling new or updated data to be immediately displayed to our users without having to reexecute queries or update the cache.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> ApolloClient <span class="hljs-keyword">from</span> <span class="hljs-string">"apollo-client"</span>;
<span class="hljs-keyword">import</span> { WebSocketLink } <span class="hljs-keyword">from</span> <span class="hljs-string">"apollo-link-ws"</span>;
<span class="hljs-keyword">import</span> { InMemoryCache } <span class="hljs-keyword">from</span> <span class="hljs-string">"apollo-cache-inmemory"</span>;

<span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> ApolloClient({
  <span class="hljs-attr">link</span>: <span class="hljs-keyword">new</span> WebSocketLink({
    <span class="hljs-attr">uri</span>: <span class="hljs-string">"wss://your-graphql-endpoint.com/v1/graphql"</span>,
    <span class="hljs-attr">options</span>: {
      <span class="hljs-attr">reconnect</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">connectionParams</span>: {
        <span class="hljs-attr">headers</span>: {
          <span class="hljs-attr">Authorization</span>: <span class="hljs-string">"Bearer yourauthtoken"</span>,
        },
      },
    },
  }),
  <span class="hljs-attr">cache</span>: <span class="hljs-keyword">new</span> InMemoryCache(),
});
</code></pre>
<h3 id="heading-providing-the-client-to-react-components">Providing the client to React components</h3>
<p>After creating a new client, passing it to all components is essential in order to be able to use it within our components to perform all of the available GraphQL operations.</p>
<p>The client is provided to the entire component tree using React Context, but instead of creating our own context, we import a special context provider from <code>@apollo/react-hooks</code> called <code>ApolloProvider</code> . We can see how it differs from the regular React Context due to it having a special prop, <code>client</code>, specifically made to accept the created client.</p>
<p>Note that all of this setup should be done in your index.js or App.js file (wherever your Routes declared) so that the Provider can be wrapped around all of your components. </p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { ApolloProvider } <span class="hljs-keyword">from</span> <span class="hljs-string">"@apollo/react-hooks"</span>;

<span class="hljs-keyword">const</span> rootElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"root"</span>);
ReactDOM.render(
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">React.StrictMode</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ApolloProvider</span> <span class="hljs-attr">client</span>=<span class="hljs-string">{client}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">BrowserRouter</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Switch</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">exact</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">component</span>=<span class="hljs-string">{App}</span> /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">exact</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/new"</span> <span class="hljs-attr">component</span>=<span class="hljs-string">{NewPost}</span> /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">exact</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/edit/:id"</span> <span class="hljs-attr">component</span>=<span class="hljs-string">{EditPost}</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Switch</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">BrowserRouter</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">ApolloProvider</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">React.StrictMode</span>&gt;</span></span>,
  rootElement
);
</code></pre>
<h3 id="heading-using-the-client-directly">Using the client directly</h3>
<p>The Apollo client is most important part of the library due to the fact that it is responsible for executing all of the GraphQL operations that we want to perform with React.</p>
<p>We can use the created client directly to perform any operation we like. It has methods corresponding to queries (<code>client.query()</code>), mutations (<code>client.mutate()</code>), and subscriptions (<code>client.subscribe()</code>). </p>
<p>Each method accepts an object and it's own corresponding properties:</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// executing queries</span>
client
  .query({
    <span class="hljs-attr">query</span>: GET_POSTS,
    <span class="hljs-attr">variables</span>: { <span class="hljs-attr">limit</span>: <span class="hljs-number">5</span> },
  })
  .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(response.data))
  .catch(<span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> <span class="hljs-built_in">console</span>.error(err));

<span class="hljs-comment">// executing mutations</span>
client
  .mutate({
    <span class="hljs-attr">mutation</span>: CREATE_POST,
    <span class="hljs-attr">variables</span>: { <span class="hljs-attr">title</span>: <span class="hljs-string">"Hello"</span>, <span class="hljs-attr">body</span>: <span class="hljs-string">"World"</span> },
  })
  .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(response.data))
  .catch(<span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> <span class="hljs-built_in">console</span>.error(err));

<span class="hljs-comment">// executing subscriptions</span>
client
  .subscribe({
    <span class="hljs-attr">subscription</span>: GET_POST,
    <span class="hljs-attr">variables</span>: { <span class="hljs-attr">id</span>: <span class="hljs-string">"8883346c-6dc3-4753-95da-0cc0df750721"</span> },
  })
  .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(response.data))
  .catch(<span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> <span class="hljs-built_in">console</span>.error(err));
</code></pre>
<p>Using the client directly can be a bit tricky, however, since in making a request, it returns a promise. To resolve each promise, we either need <code>.then()</code> and <code>.catch()</code> callbacks as above or to <code>await</code> each promise within a function declared with the <code>async</code> keyword.</p>
<h3 id="heading-writing-graphql-operations-in-js-files-gql">Writing GraphQL operations in .js files (gql)</h3>
<p>Notice above that I didn't specify the contents of the variables <code>GET_POSTS</code>, <code>CREATE_POST</code>, and <code>GET_POST</code>. </p>
<p>They are the operations written in the GraphQL syntax which specify how to perform the query, mutation, and subscription respectively. They are what we would write in any GraphiQL console to get and change data.</p>
<p>The issue here, however, is that we can't write and execute GraphQL instructions in JavaScript (.js) files, like our React code has to live in. </p>
<p>To parse the GraphQL operations, we use a special function called a tagged template literal to allow us to express them as JavaScript strings. This function is named <code>gql</code>.</p>
<pre><code class="lang-jsx">
<span class="hljs-comment">// if using apollo-boost</span>
<span class="hljs-keyword">import</span> { gql } <span class="hljs-keyword">from</span> <span class="hljs-string">"apollo-boost"</span>;
<span class="hljs-comment">// else, you can use a dedicated package graphql-tag</span>
<span class="hljs-keyword">import</span> gql <span class="hljs-keyword">from</span> <span class="hljs-string">"graphql-tag"</span>;

<span class="hljs-comment">// query</span>
<span class="hljs-keyword">const</span> GET_POSTS = gql<span class="hljs-string">`
  query GetPosts($limit: Int) {
    posts(limit: $limit) {
      id
      body
      title
      createdAt
    }
  }
`</span>;

<span class="hljs-comment">// mutation</span>
<span class="hljs-keyword">const</span> CREATE_POST = gql<span class="hljs-string">`
  mutation CreatePost($title: String!, $body: String!) {
    insert_posts(objects: { title: $title, body: $body }) {
      affected_rows
    }
  }
`</span>;

<span class="hljs-comment">// subscription</span>
<span class="hljs-keyword">const</span> GET_POST = gql<span class="hljs-string">`
  subscription GetPost($id: uuid!) {
    posts(where: { id: { _eq: $id } }) {
      id
      body
      title
      createdAt
    }
  }
`</span>;
</code></pre>
<h3 id="heading-usequery-hook">useQuery Hook</h3>
<p>The <code>useQuery</code> hook is arguably the most convenient way of performing a GraphQL query, considering that it doesn't return a promise that needs to be resolved.</p>
<p>It is called at the top of any function component (as all hooks should be) and receives as a first required argument—a query parsed with <code>gql</code>.</p>
<p>It is best used when you have queries that should be executed immediately, when a component is rendered, such as a list of data which the user would want to see immediately when the page loads.</p>
<p><code>useQuery</code> returns an object from which we can easily destructure the values that we need. Upon executing a query, there are three primary values will need to use within every component in which we fetch data. They are <code>loading</code>, <code>error</code>, and <code>data</code>.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> GET_POSTS = gql<span class="hljs-string">`
  query GetPosts($limit: Int) {
    posts(limit: $limit) {
      id
      body
      title
      createdAt
    }
  }
`</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { loading, error, data } = useQuery(GET_POSTS, {
    <span class="hljs-attr">variables</span>: { <span class="hljs-attr">limit</span>: <span class="hljs-number">5</span> },
  });

  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Error!<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;

  <span class="hljs-keyword">return</span> data.posts.map(<span class="hljs-function">(<span class="hljs-params">post</span>) =&gt;</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Post</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{post.id}</span> <span class="hljs-attr">post</span>=<span class="hljs-string">{post}</span> /&gt;</span></span>);
}
</code></pre>
<p>Before we can display the data that we're fetching, we need to handle when we're loading (when <code>loading</code> is set to true) and we are attempting to fetch the data.</p>
<p>At that point, we display a div with the text 'Loading' or a loading spinner. We also need to handle the possibility that there is an error in fetching our query, such as if there's a network error or if we made a mistake in writing our query (syntax error).</p>
<p>Once we're done loading and there's no error, we can use our data in our component, usually to display to our users (as we are in the example above).</p>
<p>There are other values which we can destructure from the object that <code>useQuery</code> returns, but you'll need <code>loading</code>, <code>error</code>, and <code>data</code> in virtually every component where you execute <code>useQuery</code>. You can see a full list of all of the data we can get back from useQuery <a target="_blank" href="https://www.apollographql.com/docs/react/api/react-hooks/#result">here</a>.</p>
<h3 id="heading-uselazyquery-hook">useLazyQuery Hook</h3>
<p>The <code>useLazyQuery</code> hook provides another way to perform a query, which is intended to be executed at some time after the component is rendered or in response to a given data change.</p>
<p><code>useLazyQuery</code> is very useful for things that happen at any unknown point of time, such as in response to a user's search operation.</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Search</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [query, setQuery] = React.useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [searchPosts, { data }] = useLazyQuery(SEARCH_POSTS, {
    <span class="hljs-attr">variables</span>: { <span class="hljs-attr">query</span>: <span class="hljs-string">`%<span class="hljs-subst">${query}</span>%`</span> },
  });
  <span class="hljs-keyword">const</span> [results, setResults] = React.useState([]);

  React.useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (!query) <span class="hljs-keyword">return</span>;
    <span class="hljs-comment">// function for executing query doesn't return a promise</span>
    searchPosts();
    <span class="hljs-keyword">if</span> (data) {
      setResults(data.posts);
    }
  }, [query, data, searchPosts]);

  <span class="hljs-keyword">if</span> (called &amp;&amp; loading) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;

  <span class="hljs-keyword">return</span> results.map(<span class="hljs-function">(<span class="hljs-params">result</span>) =&gt;</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">SearchResult</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{result.id}</span> <span class="hljs-attr">result</span>=<span class="hljs-string">{result}</span> /&gt;</span></span>
  ));
}
</code></pre>
<p><code>useLazyQuery</code> differs from <code>useQuery</code>, first of all, in what's returned from the hook. It returns an array which we can destructure, instead of an object.</p>
<p>Since we want to perform this query sometime after the component is mounted, the first element that we can destructure is a function which you can call to perform that query when you choose. This query function is named <code>searchPosts</code> in the example above.</p>
<p>The second destructured value in the array is an object, which we can use object destructuring on and from which we can get all of the same
properties as we did from <code>useQuery</code>, such as <code>loading</code>, <code>error</code>, and <code>data</code>.</p>
<p>We also get an important property named <code>called</code>,
which tells us if we've actually called this function to perform our query.
In that case, if <code>called</code> is true and <code>loading</code> is true, we want to
return "Loading..." instead of our actual data, because are waiting for the data to be returned. This is how <code>useLazyQuery</code> handles fetching data in a synchronous way without any promises.</p>
<p>Note that we again pass any required variables for the query operation as a property, variables, to the second argument. However, if we need, we can pass those variables on an object provided to the query function itself.</p>
<h3 id="heading-usemutation-hook">useMutation Hook</h3>
<p>Now that we know how to execute lazy queries, we know exactly how to work with the <code>useMutation</code> hook. </p>
<p>Like the <code>useLazyQuery</code> hook, it returns an array which we can destructure into its two elements. In the first element, we get back a function, which in this case, we can call it to perform our mutation operation. For next element, we can again destructure an object which returns to us <code>loading</code>, <code>error</code> and <code>data</code>. </p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useMutation } <span class="hljs-keyword">from</span> <span class="hljs-string">"@apollo/react-hooks"</span>;
<span class="hljs-keyword">import</span> { gql } <span class="hljs-keyword">from</span> <span class="hljs-string">"apollo-boost"</span>;

<span class="hljs-keyword">const</span> CREATE_POST = gql<span class="hljs-string">`
  mutation CreatePost($title: String!, $body: String!) {
    insert_posts(objects: { body: $body, title: $title }) {
      affected_rows
    }
  }
`</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">NewPost</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [title, setTitle] = React.useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [body, setBody] = React.useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [createPost, { loading, error }] = useMutation(CREATE_POST);

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleCreatePost</span>(<span class="hljs-params">event</span>) </span>{
    event.preventDefault();
    <span class="hljs-comment">// the mutate function also doesn't return a promise</span>
    createPost({ <span class="hljs-attr">variables</span>: { title, body } });
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>New Post<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleCreatePost}</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(event)</span> =&gt;</span> setTitle(event.target.value)} /&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(event)</span> =&gt;</span> setBody(event.target.value)} /&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">disabled</span>=<span class="hljs-string">{loading}</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>
          Submit
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        {error &amp;&amp; <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{error.message}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>}
      <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>Unlike with queries, however, we don't use <code>loading</code> or <code>error</code> in order to conditionally render something. We generally use <code>loading</code> in such situations as when we're submitting a form to prevent it being submitted multiple times, to avoid executing the same mutation needlessly (as you can see in the example above). </p>
<p>We use <code>error</code> to display what goes wrong with our mutation to our users. If for example, some required values to our mutation are not provided, we can easily use that error data to conditionally render an error message within the page so the user can hopefully fix what's going wrong.</p>
<p>As compared to passing variables to the second argument of <code>useMutation</code>, we can access a couple of useful callbacks when certain things take place, such as when the mutation is completed and when there is an error. These callbacks are named <code>onCompleted</code> and <code>onError</code>. </p>
<p>The <code>onCompleted</code> callback gives us access to the returned mutation data and it's very helpful to do something when the mutation is done, such as going to a different page. The <code>onError</code> callback gives us the returned error when there is a problem with the mutation and gives us other patterns for handling our errors.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> [createPost, { loading, error }] = useMutation(CREATE_POST, {
  <span class="hljs-attr">onCompleted</span>: <span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Data from mutation"</span>, data),
  <span class="hljs-attr">onError</span>: <span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error creating a post"</span>, error),
});
</code></pre>
<h3 id="heading-usesubscription-hook">useSubscription Hook</h3>
<p>The useSubscription hook works just like the useQuery hook. </p>
<p>useSubscription returns an object that we can destructure, that includes the same properties, loading, data, and error. </p>
<p>It executes our subscription immediately when the component is rendered. This means we  need to handle loading and error states, and only afterwards display/use our data.  </p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useSubscription } <span class="hljs-keyword">from</span> <span class="hljs-string">"@apollo/react-hooks"</span>;
<span class="hljs-keyword">import</span> gql <span class="hljs-keyword">from</span> <span class="hljs-string">"graphql-tag"</span>;

<span class="hljs-keyword">const</span> GET_POST = gql<span class="hljs-string">`
  subscription GetPost($id: uuid!) {
    posts(where: { id: { _eq: $id } }) {
      id
      body
      title
      createdAt
    }
  }
`</span>;

<span class="hljs-comment">// where id comes from route params -&gt; /post/:id</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PostPage</span>(<span class="hljs-params">{ id }</span>) </span>{
  <span class="hljs-keyword">const</span> { loading, error, data } = useSubscription(GET_POST, {
    <span class="hljs-attr">variables</span>: { id },
    <span class="hljs-comment">// shouldResubscribe: true (default: false)</span>
    <span class="hljs-comment">// onSubscriptionData: data =&gt; console.log('new data', data)</span>
    <span class="hljs-comment">// fetchPolicy: 'network-only' (default: 'cache-first')</span>
  });

  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Error!<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;

  <span class="hljs-keyword">const</span> post = data.posts[<span class="hljs-number">0</span>];

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>{post.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{post.body}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>Just like useQuery, useLazyQuery and useMutation, useSubscription accepts <code>variables</code> as a property provided on the second argument. </p>
<p>It also accepts, however, some useful properties such as <code>shouldResubscribe</code>. This is a boolean value, which will allow our subscription to automatically resubscribe, when our props change. This is useful for when we're passing variables to our you subscription hub props that we know will change. </p>
<p>Additionally, we have a callback function called <code>onSubscriptionData</code>, which enables us to call a function whenever the subscription hook receives new data. Finally, we can set the <code>fetchPolicy</code>, which defaults to 'cache-first'.</p>
<h3 id="heading-manually-setting-the-fetch-policy">Manually Setting the Fetch Policy</h3>
<p>What can be very useful about Apollo is that it comes with its own cache, which it uses to manage the data that we query from our GraphQL endpoint. </p>
<p>Sometimes, however, we find that due to this cache, things aren't updated in the UI in the way that we want. </p>
<p>In many cases we don't, as in the example below, where we are editing a post on the edit page, and then after editing our post, we navigate to the home page to see it in a list of all posts, but we see the old data instead:</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// route: /edit/:postId</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">EditPost</span>(<span class="hljs-params">{ id }</span>) </span>{
  <span class="hljs-keyword">const</span> { loading, data } = useQuery(GET_POST, { <span class="hljs-attr">variables</span>: { id } });
  <span class="hljs-keyword">const</span> [title, setTitle] = React.useState(loading ? data?.posts[<span class="hljs-number">0</span>].title : <span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [body, setBody] = React.useState(loading ? data?.posts[<span class="hljs-number">0</span>].body : <span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [updatePost] = useMutation(UPDATE_POST, {
    <span class="hljs-comment">// after updating the post, we go to the home page</span>
    <span class="hljs-attr">onCompleted</span>: <span class="hljs-function">() =&gt;</span> history.push(<span class="hljs-string">"/"</span>),
  });

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleUpdatePost</span>(<span class="hljs-params">event</span>) </span>{
    event.preventDefault();
    updatePost({ <span class="hljs-attr">variables</span>: { title, body, id } });
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleUpdatePost}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(event)</span> =&gt;</span> setTitle(event.target.value)}
        defaultValue={title}
      /&gt;
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(event)</span> =&gt;</span> setBody(event.target.value)}
        defaultValue={body}
      /&gt;
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
  );
}

<span class="hljs-comment">// route: / (homepage)</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { loading, error, data } = useQuery(GET_POSTS, {
    <span class="hljs-attr">variables</span>: { <span class="hljs-attr">limit</span>: <span class="hljs-number">5</span> },
  });

  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Error!<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;

  <span class="hljs-comment">// updated post not displayed, still see old data</span>
  <span class="hljs-keyword">return</span> data.posts.map(<span class="hljs-function">(<span class="hljs-params">post</span>) =&gt;</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Post</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{post.id}</span> <span class="hljs-attr">post</span>=<span class="hljs-string">{post}</span> /&gt;</span></span>);
}
</code></pre>
<p>This not only due to the Apollo cache, but also the instructions for what data the query should fetch. We can changed how the query is fetched by using the <code>fetchPolicy</code> property. </p>
<p>By default, the <code>fetchPolicy</code> is set to 'cache-first'. It's going to try to look at the cache to get our data instead of getting it from the network. </p>
<p>An easy way to fix this problem of not seeing new data is to change the fetch policy. However, this approach is not ideal from a performance standpoint, because it requires making an additional request (using the cache directly does not, because it is local data). </p>
<p> There are many different options for the fetch policy listed below:</p>
<pre><code class="lang-jsx">{
  <span class="hljs-attr">fetchPolicy</span>: <span class="hljs-string">"cache-first"</span>; <span class="hljs-comment">// default</span>
  <span class="hljs-comment">/* 
    cache-and-network
    cache-first
    cache-only
    network-only
    no-cache
    standby
  */</span>
}
</code></pre>
<p>I won't go into what each policy does exactly, but to solve our immediate problem, if you always want a query to get the latest data by requesting it from the network, we set <code>fetchPolicy</code> to 'network-first'.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> { loading, error, data } = useQuery(GET_POSTS, {
  <span class="hljs-attr">variables</span>: { <span class="hljs-attr">limit</span>: <span class="hljs-number">5</span> },
  <span class="hljs-attr">fetchPolicy</span>: <span class="hljs-string">"network-first"</span>
});
</code></pre>
<h3 id="heading-updating-the-cache-upon-a-mutation">Updating the cache upon a mutation</h3>
<p>Instead of bypassing the cache by changing the fetch policy of <code>useQuery</code>, let's attempt to fix this problem by manually updating the cache. </p>
<p>When performing a mutation with <code>useMutation</code>. We have access to another callback, known as <code>update</code>. </p>
<p><code>update</code> gives us direct access to the cache as well as the data that is returned from a successful mutation. This enables us to read a given query from the cache, take that new data and write the new data to the query, which will then update what the user sees. </p>
<p>Working with the cache manually is a tricky process that a lot of people tend to avoid, but it's very helpful because it saves some time and resources by not having to perform the same request multiple times to update the cache manually. </p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">EditPost</span>(<span class="hljs-params">{ id }</span>) </span>{
  <span class="hljs-keyword">const</span> [updatePost] = useMutation(UPDATE_POST, {
    <span class="hljs-attr">update</span>: <span class="hljs-function">(<span class="hljs-params">cache, data</span>) =&gt;</span> {
      <span class="hljs-keyword">const</span> { posts } = cache.readQuery(GET_POSTS);
      <span class="hljs-keyword">const</span> newPost = data.update_posts.returning;
      <span class="hljs-keyword">const</span> updatedPosts = posts.map(<span class="hljs-function">(<span class="hljs-params">post</span>) =&gt;</span>
        post.id === id ? newPost : post
      );
      cache.writeQuery({ <span class="hljs-attr">query</span>: GET_POSTS, <span class="hljs-attr">data</span>: { <span class="hljs-attr">posts</span>: updatedPosts } });
    },
    <span class="hljs-attr">onCompleted</span>: <span class="hljs-function">() =&gt;</span> history.push(<span class="hljs-string">"/"</span>),
  });

  <span class="hljs-comment">// ...</span>
}
</code></pre>
<p>We first want to read the query and get the previous data from it. Then we need to take the new data. In this case, to find the post with a given id and replace it with <code>newPost</code> data, otherwise have it be the previous data, and then write that data back to the same query, making sure that it has the same data structure as before. </p>
<p>After all this, whenever we edit a post and are navigated back to the home page, we should see that new post data.</p>
<h3 id="heading-refetching-queries-with-usequery">Refetching queries with useQuery</h3>
<p>Let's say we display a list of posts using a <code>GET_POSTS</code> query and are deleting one of them with a <code>DELETE_POST</code> mutation.</p>
<p>When a user deletes a post, what do we want to happen?</p>
<p>Naturally, we want it to be removed from the list, both the data and what is displayed to the users. When a mutation is performed, however, the query doesn't know that the data is changed. </p>
<p>There are a few ways of updating what we see, but one approach is to reexecute the query. </p>
<p>We can do so by grabbing the <code>refetch</code> function which we can destructure from the object returned by the <code>useQuery</code> hook and pass it down to the mutation to be executed when it is completed, using the <code>onCompleted</code> callback function:</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Posts</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { loading, data, refetch } = useQuery(GET_POSTS);

  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;

  <span class="hljs-keyword">return</span> data.posts.map(<span class="hljs-function">(<span class="hljs-params">post</span>) =&gt;</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Post</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{post.id}</span> <span class="hljs-attr">post</span>=<span class="hljs-string">{post}</span> <span class="hljs-attr">refetch</span>=<span class="hljs-string">{refetch}</span> /&gt;</span></span>
  ));
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Post</span>(<span class="hljs-params">{ post, refetch }</span>) </span>{
  <span class="hljs-keyword">const</span> [deletePost] = useMutation(DELETE_POST, {
    <span class="hljs-attr">onCompleted</span>: <span class="hljs-function">() =&gt;</span> refetch(),
  });

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleDeletePost</span>(<span class="hljs-params">id</span>) </span>{
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">window</span>.confirm(<span class="hljs-string">"Are you sure you want to delete this post?"</span>)) {
      deletePost({ <span class="hljs-attr">variables</span>: { id } });
    }
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>{post.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{post.body}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> handleDeletePost(post.id)}&gt;Delete<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<h3 id="heading-refetching-queries-with-usemutation">Refetching Queries with useMutation</h3>
<p>Note that we can also utilize the <code>useMutation</code> hook to reexecute our queries through an argument provided to the mutate function, called <code>refetchQueries</code>. </p>
<p>It accepts an array of queries that we want to refetch after a mutation is performed. Each queries is provided within an object, just like we would provide it to client.query(), and consists of a query property and a variables property. </p>
<p>Here is a minimal example to refetch our <code>GET_POSTS</code> query after a new post is created:</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">NewPost</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [createPost] = useMutation(CREATE_POST, {
    <span class="hljs-attr">refetchQueries</span>: [
      { 
        <span class="hljs-attr">query</span>: GET_POSTS, 
        <span class="hljs-attr">variables</span>: { <span class="hljs-attr">limit</span>: <span class="hljs-number">5</span> } 
      }
    ],
  });

  <span class="hljs-comment">// ...</span>
}
</code></pre>
<h3 id="heading-using-the-client-with-useapolloclient">Using the client with useApolloClient</h3>
<p>We can get access to the client across our components with the help of a special hook called use Apollo client. This execute the hook at the top of our function component and we get back the client itself. </p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Logout</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> client = useApolloClient();
  <span class="hljs-comment">// client is the same as what we created with new ApolloClient()</span>

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleLogout</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// handle logging out user, then clear stored data</span>
    logoutUser();
    client.resetStore().then(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"logged out!"</span>));
    <span class="hljs-comment">/* Be aware that .resetStore() is async */</span>
  }

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleLogout}</span>&gt;</span>Logout<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
}
</code></pre>
<p>And from there we can execute all the same queries, mutations, and subscriptions.</p>
<p>Note that there are a ton more features that come with methods that come with the client. Using the client, we can also write and read data to and from the cache that Apollo sets up (using <code>client.readData()</code> and <code>client.writeData()</code>). </p>
<p>Working with the Apollo cache deserves its own crash course in itself. A great benefit of working with Apollo is that we can also use it as a state management system to replace solutions like Redux for our global state. If you want to learn more about using Apollo to manage global app state you can <a target="_blank" href="https://www.apollographql.com/docs/react/data/local-state/">check out the following link</a>.</p>
<p>I attempted to make this cheatsheet as comprehensive as possible, though it still leaves out many Apollo features that are worth investigating. </p>
<p>If you want to more about Apollo, be sure to check out the <a target="_blank" href="https://www.apollographql.com/docs/react/">official Apollo documentation</a>.</p>
<h3 id="heading-download-the-cheatsheet">Download the cheatsheet</h3>
<p>Want a quick reference of all of these concepts?</p>
<p><a target="_blank" href="https://reedbarger.com/resources/react-apollo-2020/"><img src="https://dev-to-uploads.s3.amazonaws.com/i/7herw99hu78t8gspo88d.png" alt="React and Apollo 2020 Cheatsheet" width="762" height="500" loading="lazy"></a><em>Click to grab the complete PDF cheatsheet</em></p>
<h2 id="heading-become-a-professional-react-developer">Become a Professional React Developer</h2>
<p>React is hard. You shouldn't have to figure it out yourself.</p>
<p>I've put everything I know about React into a single course, to help you reach your goals in record time:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><strong>Introducing: The React Bootcamp</strong></a></p>
<p><strong>It’s the one course I wish I had when I started learning React.</strong></p>
<p>Click below to try the React Bootcamp for yourself:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><img src="https://reedbarger.nyc3.digitaloceanspaces.com/reactbootcamp/react-bootcamp-cta-alt.png" alt="Click to join the React Bootcamp" width="600" height="400" loading="lazy"></a>
<em>Click to get started</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The React + GraphQL 2020 Crash Course ]]>
                </title>
                <description>
                    <![CDATA[ Have you heard a lot about using React with GraphQL but don't know how to combine them to build amazing apps? In this crash course, you'll learn how to do just that by building a complete social blogging app.  Within an afternoon, you will gain the c... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-react-graphql-2020-crash-course/</link>
                <guid isPermaLink="false">66d037fa386d35c4e3bb3c26</guid>
                
                    <category>
                        <![CDATA[ 2020 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Apollo GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ apollo client ]]>
                    </category>
                
                    <category>
                        <![CDATA[ beginner ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react hooks ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Reed ]]>
                </dc:creator>
                <pubDate>Tue, 30 Jun 2020 13:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/06/React---GraphQL-2020-Crash-Course-Cover--Large--1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Have you heard a lot about using React with GraphQL but don't know how to combine them to build amazing apps? In this crash course, you'll learn how to do just that by building a complete social blogging app. </p>
<p>Within an afternoon, you will gain the core skills to build your own React and GraphQL projects.</p>
<h2 id="heading-why-you-should-learn-react-with-graphql">Why you should learn React with GraphQL ?</h2>
<p>React is the go-to library for building amazing app experiences with JavaScript. GraphQL, on the other hand, is a tool that gives us a better, more straightforward means of getting and changing our data.</p>
<p>That data could be from a standard database (as we'll be using in our app) or as React frameworks like Gatsby have made possible, even from static files such as markdown files. Regardless of how it's stored, GraphQL makes working with data in our apps better.</p>
<p>We'll see how to leverage the powers of React and GraphQL by creating a social blogging app from start to finish, where you can create, read, edit and delete posts.</p>
<p><a target="_blank" href="https://bit.ly/2020-react-graphql"><img src="https://dev-to-uploads.s3.amazonaws.com/i/o51wpa2tgx9k85p8rse8.gif" alt="Click to access the course" width="1280" height="720" loading="lazy"></a></p>
<p>You can <a target="_blank" href="https://courses.reedbarger.com/p/2020-react-graphql">click here</a> to access the course.</p>
<h2 id="heading-what-tools-well-be-using">What tools we'll be using ?️</h2>
<p>The crash course is meant for developers who are somewhat familiar with React (including the core React Hooks, such as <code>useState</code> and <code>useEffect</code>), but aren't familiar with GraphQL yet.</p>
<p>Basic React knowledge is assumed, but GraphQL knowledge is not required. We'll cover all the core GraphQL concepts you need along the way.</p>
<p>Throughout the course, we'll utilize the following technologies to create our app:</p>
<ul>
<li><strong>React</strong> (to build our user interface)</li>
<li><strong>GraphQL</strong> (to get and change data in a declarative way)</li>
<li><strong>Apollo Client</strong> (to allow us to use React and GraphQL together)</li>
<li><strong>Hasura</strong> (to create and manage our GraphQL API + database)</li>
</ul>
<p>To top it off, we'll be using the online IDE CodeSandbox. This will allow us to code our entire application within the browser in realtime, without the need to create any files, folders, or install dependencies on our own.</p>
<h2 id="heading-creating-a-graphql-api-from-scratch">Creating a GraphQL API from scratch</h2>
<p>To get started working with GraphQL, we'll see how to make an entire GraphQL API from scratch that will communicate with our database. </p>
<p>Fortunately, using the (free) service <strong>Hasura</strong>, this process is very simple and straightforward. Within seconds, we'll see how to create and deploy a complete GraphQL API to the web, which is connected to a Postgres database that will take care of storing our app data.</p>
<p><a target="_blank" href="https://learn.codeartistry.io/courses/2020-react-graphql/lectures/19445637"><img src="https://dev-to-uploads.s3.amazonaws.com/i/ss4wp2tt4ernoe5ukea8.png" alt="Click to access the course" width="1104" height="731" loading="lazy"></a><em>Click to watch this lecture</em></p>
<h2 id="heading-getting-familiar-with-graphql">Getting familiar with GraphQL</h2>
<p>In the second lecture, we'll cover how to write in the GraphQL language using our API's built-in console called <strong>GraphiQL</strong>. </p>
<p>First, we will create a table in our database for all of our posts data. After which, Hasura will automatically create the <strong>queries</strong> and <strong>mutations</strong> we need, which are the names of GraphQL operations that allow us to get and change data in our database. </p>
<p>Throughout this lesson, we'll get very familiar performing queries and mutations in GraphiQL, which will enable us to get entire sets of posts and individual posts, as well as to create, update, and delete our individual post data. </p>
<p><a target="_blank" href="https://learn.codeartistry.io/courses/2020-react-graphql/lectures/19445640"><img src="https://dev-to-uploads.s3.amazonaws.com/i/bo5twcv0hhal7xtj1ksw.png" alt="Click to access the course" width="1280" height="800" loading="lazy"></a><em>Click to watch this lecture</em></p>
<h2 id="heading-connecting-react-with-our-graphql-api-using-apollo-client">Connecting React with our GraphQL API using Apollo Client</h2>
<p>Now that we're comfortable with using GraphQL and understand its core features, we'll see how to connect it with our React client. </p>
<p>The way that we connect our React app with the GraphQL API we created is through a library called <strong>Apollo</strong>. We'll see how to set up the Apollo client, by providing the GraphQL endpoint, which points to our API, like so:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> ApolloClient <span class="hljs-keyword">from</span> <span class="hljs-string">"apollo-boost"</span>;

<span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> ApolloClient({
  <span class="hljs-attr">uri</span>: <span class="hljs-string">"https://react-graphql.herokuapp.com/v1/graphql"</span>
});
</code></pre>
<p>With our newly created client, we have the ability to execute any GraphQL operation through React. To do this, however, we need to pass our client to our entire to all of our React components. We do that with the help of the Apollo provider, as you see below:</p>
<p><a target="_blank" href="https://learn.codeartistry.io/courses/2020-react-graphql/lectures/19445642"><img src="https://dev-to-uploads.s3.amazonaws.com/i/iplsbo37x2oujohn7ulc.png" alt="Click to access the course" width="1280" height="800" loading="lazy"></a><em>Click to watch this lecture</em></p>
<h3 id="heading-getting-posts-with-usequery">Getting posts with useQuery</h3>
<p>After setting up our client, we'll see how to execute different GraphQL operations with them, using some special React hooks that come with the package <code>@apollo/react-hooks</code>.</p>
<p>The hook that allows us to query for data with GraphQL is called <code>useQuery</code>. With it, we'll first see how to get and display all of our post data in our homepage.</p>
<p>Additionally, we'll learn how to write our GraphQL queries directly in our JavaScript files with the help of a special function called <code>gql</code>.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { useQuery } <span class="hljs-keyword">from</span> <span class="hljs-string">"@apollo/react-hooks"</span>;
<span class="hljs-keyword">import</span> { gql } <span class="hljs-keyword">from</span> <span class="hljs-string">"apollo-boost"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> GET_POSTS = gql<span class="hljs-string">`
  query getPosts {
    posts {
      id
      title
      body
      createdAt
    }
  }
`</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { data, loading } = useQuery(GET_POSTS);

  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
  <span class="hljs-keyword">if</span> (data.posts.length === <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Empty</span> /&gt;</span></span>;

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{classes.header}</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{classes.h2}</span>&gt;</span>All Posts<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/new"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{classes.newPost}</span>&gt;</span>
          New Post
        <span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
      {data.posts.map(post =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">Post</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{post.id}</span> <span class="hljs-attr">post</span>=<span class="hljs-string">{post}</span> /&gt;</span>
      ))}
    <span class="hljs-tag">&lt;/&gt;</span></span>
  );
}
</code></pre>
<h2 id="heading-creating-and-editing-new-posts-with-usemutation">Creating and editing new posts with useMutation</h2>
<p>After that, we'll see how to create new posts with the <code>useMutation</code> hook. In order to do this, we'll take a look at how to work with GraphQL variables to pass our mutation dynamic values that will change with each execution. </p>
<p>Following that we'll take a look at how to edit our posts. To do so, we'll need to fetch an individual post and display it within our form, so that our user can make changes to the data. Then we'll need to execute a mutation that will perform the update, based on the posts id. </p>
<p><a target="_blank" href="https://learn.codeartistry.io/courses/2020-react-graphql/lectures/19445643"><img src="https://dev-to-uploads.s3.amazonaws.com/i/n9swv8j0qr962spqxhkx.png" alt="Click to access the course" width="1280" height="800" loading="lazy"></a><em>Click to watch this lecture</em></p>
<h2 id="heading-handle-loading-and-errors">Handle loading and errors</h2>
<p>In the following lecture, we'll cover some essential patterns for handling the process of loading our data. </p>
<p>It's important to do so when we execute a mutation, to make sure we don't submit our forms multiple times as our mutation is being executed. We'll also take a look at how to handle errors in the event that our mutation is not executed correctly. </p>
<p><a target="_blank" href="https://learn.codeartistry.io/courses/2020-react-graphql/lectures/19445638"><img src="https://dev-to-uploads.s3.amazonaws.com/i/548ekws3psm3cbfpqy8e.png" alt="Click to access the course" width="1280" height="800" loading="lazy"></a><em>Click to watch this lecture</em></p>
<h2 id="heading-deleting-posts">Deleting posts</h2>
<p>Finally, we'll cover how to delete posts from our app. First, we'll confirm that the user wants to actually delete the post that they've made, then perform the mutation. </p>
<p>Additionally, we'll take a look at how to update our UI in response to mutations with  the helpful <code>refetch</code> function that Apollo gives us. It will enable us to re-execute a query on demand. In this case, we'll do it after the delete mutation has been successfully performed.</p>
<p><a target="_blank" href="https://learn.codeartistry.io/courses/2020-react-graphql/lectures/19445639"><img src="https://dev-to-uploads.s3.amazonaws.com/i/ojjd4jjxuh0h7p1048ck.png" alt="Click to access the course" width="1280" height="800" loading="lazy"></a><em>Click to watch this lecture</em></p>
<h2 id="heading-become-a-professional-react-developer">Become a Professional React Developer</h2>
<p>React is hard. You shouldn't have to figure it out yourself.</p>
<p>I've put everything I know about React into a single course, to help you reach your goals in record time:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><strong>Introducing: The React Bootcamp</strong></a></p>
<p><strong>It’s the one course I wish I had when I started learning React.</strong></p>
<p>Click below to try the React Bootcamp for yourself:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><img src="https://reedbarger.nyc3.digitaloceanspaces.com/reactbootcamp/react-bootcamp-cta-alt.png" alt="Click to join the React Bootcamp" width="600" height="400" loading="lazy"></a>
<em>Click to get started</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to do Apollo HOC mutations the right way ]]>
                </title>
                <description>
                    <![CDATA[ By Lachlan Young Chances are, like many people, you’re coming to Apollo and GraphQL from a REST API background. Yet as you begin to explore the working examples of this stack and the different ways to implement it, you will no doubt be tripped up on ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/do-apollo-hoc-mutations-goodly-bb4effdbee94/</link>
                <guid isPermaLink="false">66c349545ced6d98e4bd32b8</guid>
                
                    <category>
                        <![CDATA[ apollo client ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 04 Dec 2018 06:39:43 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*C1932-kODhSC6ibR7kUxNA.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Lachlan Young</p>
<p>Chances are, like many people, you’re coming to Apollo and GraphQL from a REST API background. Yet as you begin to explore the working examples of this stack and the different ways to implement it, you will no doubt be tripped up on a multitude of differences, whether it’s Apollo’s Libraries, or the entire ‘get your data as you want it’ mentality around GraphQL and Apollo’s render components.</p>
<p>What I want to do in this article is help address two of the key issues when writing a mutation. This primarily targets HOC implementations, however it is more or less the same for the render components, tweaking object keys to props instead.</p>
<p>Specifically, we will be jumping straight into the optimisticResponse along with the update parameters of your HOC mutation. It is my hope that this will make you more aware of what options you have when it comes to implementing a mutation as a prop function.</p>
<p><strong>Important:</strong> If you are only just getting started with Apollo, I wholeheartedly implore you to implement their render components that they released around version 2.1. HOCs are soft deprecated and as such, are missing a lot of their documentation, as mentioned by a few people <a target="_blank" href="https://github.com/apollographql/apollo-client/issues/3253">here</a>.</p>
<h3 id="heading-optimistic-response">Optimistic Response</h3>
<p>optimisticResponse is the way we manage if our app is online or not along with the status of our requests to the DB.</p>
<p>If we mutate our database without a connection, the optimistic response allows it to exist with variables that we reasonably expect.</p>
<p><strong>For example</strong>, if we assume that we will add this user to the db:</p>
<pre><code>{    <span class="hljs-attr">userId</span>: <span class="hljs-number">123</span>,    <span class="hljs-attr">firstName</span>: <span class="hljs-string">"Lachlan"</span>,    <span class="hljs-attr">lastName</span>: <span class="hljs-string">"Young"</span>,    <span class="hljs-attr">status</span>: <span class="hljs-string">"Hungry"</span>}
</code></pre><p>We would want to update our user details with the above data. However, because of the way our mutations work (and this is specifically for HOCs but can be applied to Render components too), there is a lifecycle to the mutation, going from loading, to success/fail/can’t connect.</p>
<p>If at any point the mutation fails but does not error, your Apollo client knows that this was because of something other than a bad object. By this I mean it takes into account your offline status, the status of the request, and it will instead render that user to the user details component, because it assumes it is valid. Therefore your client is being optimistic.</p>
<p>When you connect to the internet again or reach your DB, it will update the response with the valid data. Inside of that response you can handle stuff like userId’s which you generate on the client, therefore updating my hardcoded id of 123, to a UUID.</p>
<p>If we weren’t online we could still see and interact with the request as expected and any changes would be queued to then mutate the server upon reconnecting.</p>
<p>That’s an optimistic response.</p>
<h3 id="heading-update">Update</h3>
<p>As for how to handle the response from the database, you actually have access to a property called <strong>update</strong>, and for HOCs it looks like this:</p>
<pre><code>update: <span class="hljs-function">(<span class="hljs-params">proxy, { data: { myDetails } }</span>) =&gt;</span> {    <span class="hljs-keyword">try</span> {        <span class="hljs-comment">// Read the data from our cache for this query.        const data = proxy.readQuery({             query: gql`${GET_MY_DETAILS}`        });</span>
</code></pre><pre><code>        <span class="hljs-comment">// Add our new request from the mutation to the end.        data.getMyDetails.push(myDetails);</span>
</code></pre><pre><code>        <span class="hljs-comment">// Write our data back to the cache.        proxy.writeQuery({             query: gql`${GET_MY_DETAILS}`,            data        });    } catch (err) {        console.log('Error updating the cahche: ', err.message);    }}</span>
</code></pre><p>Essentially this comes after the optimisticResponse field in the mutation. It directly handles what happens after you receive a response, taking it from the top it has <code>proxy</code> and <code>data</code> as it’s two arguments. <code>Proxy</code> is quite literally our client, however for some configurations you may be better served referencing it as the cache. <code>Data</code> is the response from the mutation. I’ve deconstructed it, in this case, to explain the myDetails object further.</p>
<p><strong>myDetails</strong> consists of everything in the user object above, but the id will now be a valid UUID instead of 123. We then use the apolloClient’s methods for reading and writing and read the details we have saved in our cache. From there we add our new details and re-write them to the cache. This way after I navigate back to my details from the input page, my new details will instantly be available because they are the point of truth in the cache.</p>
<h3 id="heading-additional-information">Additional Information</h3>
<p>As of writing this, all the render props documented <a target="_blank" href="https://www.apollographql.com/docs/react/api/react-apollo.html#mutation-props">here</a>, or seen below for longevitiy, can be applied to your HOC mutation. As I mentioned in the introduction to this article, the HOC documentation has indeed been deprecated. However, the options given below can all be implemented as keys to the HOC object.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/ZSBBl-U4RRMGxZ6RavWDiL0RRlvTi5-h92MP" alt="Image" width="800" height="747" loading="lazy">
<em>Mutation Props <strong>4/12/2018</strong></em></p>
<p>Thank you very much for reading. You can usually see me floating around the Apollo Slack in either the #React-Apollo or #Apollo-Client channels. To register for the slack and get more specific advice, click <a target="_blank" href="https://www.apollographql.com/slack/">here</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
