The React + GraphQL 2020 Crash Course: Build a Complete App in an Afternoon
React and GraphQL are two of the hottest technologies in web development today. React is a powerful JavaScript library for building interactive user interfaces, while GraphQL is a query language that gives frontend developers a more efficient and flexible way to fetch data from APIs.
When you combine the component-based architecture of React with the declarative data fetching of GraphQL, you get a robust and scalable approach for building modern web applications. In this crash course, you‘ll learn how to use React and GraphQL together by building a complete social blogging app from start to finish.
Why Use React with GraphQL?
So what makes React and GraphQL such a great fit? Let‘s look at some of the key benefits:
Declarative data fetching: With GraphQL, you define the shape of the data you need right in your React component. No need to manually construct HTTP requests or parse responses. Just describe your data requirements and let GraphQL handle the details.
Efficient network requests: GraphQL allows you to batch multiple queries into a single request. Instead of making separate API calls for each piece of data, you can retrieve everything in one trip to the server. This minimizes network overhead and improves performance.
No over/under-fetching: With REST APIs, it‘s common to fetch more data than you actually need (over-fetching) or make multiple requests to get all the necessary data (under-fetching). GraphQL eliminates this by allowing you to request exactly what you need, no more and no less.
Strong typing: GraphQL APIs are strongly typed, which means you get validation and auto-completion out of the box. This catches bugs early and makes it easier to explore and understand the API surface.
Rapid development: By leveraging GraphQL tooling and libraries like Apollo Client, you can quickly prototype and build React apps without getting bogged down in the details of data fetching. This lets you focus on crafting the perfect user experience.
Key Concepts and Tools
Before we dive into building our app, let‘s take a quick look at some of the key concepts and tools we‘ll be using:
React Hooks: React Hooks are functions that let you "hook into" React state and lifecycle features from functional components. We‘ll be using the useState and useEffect hooks to manage local component state and side effects.
Apollo Client: Apollo Client is a popular GraphQL client that integrates seamlessly with React. It handles state management, caching, and other complex concerns, allowing you to focus on the core logic of your components.
Hasura: Hasura is a service that instantly gives you a production-ready GraphQL API. We‘ll use it to generate a GraphQL API and hook it up to a Postgres database without writing any backend code.
CodeSandbox: CodeSandbox is an online code editor that makes it easy to prototype and share web apps. We‘ll be using it throughout the course so you can code along without worrying about local setup.
Now that we have a foundation, let‘s walk through the steps of the crash course and see how these pieces fit together.
Step 1: Create a GraphQL API
The first step is to create our GraphQL API using Hasura. After signing up for a free account, you can create a new Hasura project with just a few clicks. This will provision a Postgres database and generate a GraphQL API that maps to your database schema.
One of the coolest features of Hasura is that it automatically generates GraphQL mutations for creating, updating, and deleting records in your database. As soon as we define our data model, we have a complete CRUD API without writing any resolvers!
Step 2: Learn GraphQL Queries and Mutations
With our API in place, it‘s time to start exploring GraphQL. Hasura provides a built-in tool called GraphiQL, which is an interactive playground for running queries and mutations against your API.
We‘ll start by defining a simple data model for our blog posts. Each post will have an id, title, body, and createdAt timestamp. Then we can use GraphiQL to execute queries that fetch posts from the database.
Here‘s an example query that retrieves a list of all posts:
query {
posts {
id
title
body
createdAt
}
}
GraphiQL also lets us test out mutations for creating, updating, and deleting posts. Here‘s a mutation that creates a new post:
mutation {
insert_posts_one(object: {
title: "My First Post",
body: "Hello world!"
}) {
id
title
body
createdAt
}
}
By the end of this step, you‘ll be proficient in the GraphQL query language and ready to integrate it into a React app.
Step 3: Connect React with Apollo Client
Now that our API is set up, let‘s connect it to a React frontend using Apollo Client. The first step is to install the apollo-boost and @apollo/react-hooks packages.
Next, we create a new ApolloClient instance and specify the URL of our GraphQL API:
import ApolloClient from ‘apollo-boost‘;
const client = new ApolloClient({
uri: ‘https://my-app.herokuapp.com/v1/graphql‘,
});
Finally, we wrap our React app in an ApolloProvider component and pass in the client. This makes the GraphQL API available to all of our components.
import { ApolloProvider } from ‘@apollo/react-hooks‘;
ReactDOM.render(
,
document.getElementById(‘root‘)
);
With that, our React app is fully powered by GraphQL and ready to fetch some data!
Step 4: Fetch Data with useQuery
One of the best parts about using Apollo with React is the useQuery hook. This lets you execute GraphQL queries and render the results in your component with minimal boilerplate.
First we define our GraphQL query using the gql template literal:
import { gql } from ‘apollo-boost‘;
const GET_POSTS = gql query { posts { id title body createdAt } }
;
Then we pass our query to the useQuery hook:
import { useQuery } from ‘@apollo/react-hooks‘;
function PostList() {
const { data, loading, error } = useQuery(GET_POSTS);
if (loading) return
Loading…
;
if (error) return
Error 🙁
;
return (
-
{data.posts.map(post => (
-
{post.title}
{post.body}
))}
);
}
That‘s it! The useQuery hook handles executing our query and tracking the loading and error states. We can focus on rendering the fetched data in our component.
Step 5: Create and Edit Data with useMutation
In addition to fetching data, our app needs to be able to create and edit blog posts. Apollo makes this easy with the useMutation hook.
To create a post, we define a GraphQL mutation:
const CREATE_POST = gql mutation CreatePost($title: String!, $body: String!) { insert_posts_one(object: {title: $title, body: $body}) { id title body createdAt } }
;
Then we execute it with useMutation:
function CreatePost() {
const [createPost, { loading }] = useMutation(CREATE_POST);
function handleSubmit(event) {
event.preventDefault();
createPost({
variables: {
title: event.target.elements.title.value,
body: event.target.elements.body.value
}
});
}
return (
);
}
The useMutation hook returns a function that executes the mutation as well as an object with loading and error states. We call the function with the mutation variables and it sends the insert_posts_one mutation to our API.
Editing a post follows a similar pattern. We fetch the post by id, populate a form with the post data, and execute an update_posts_by_pk mutation on form submit.
Step 6: Handle Loading and Errors
You might have noticed the loading and error states returned from the useQuery and useMutation hooks. These let us show loading indicators and error messages while data is being fetched.
It‘s important to handle these states gracefully so the user knows what‘s happening at all times. Here‘s an example of showing a loading spinner while creating a post:
function CreatePost() {
const [createPost, { loading, error }] = useMutation(CREATE_POST);
if (loading) return
Submitting…
;
if (error) return
Error :( Please try again
;
return (
{/ form goes here /}
);
}
We can apply this same pattern throughout our app to guide the user and communicate the state of our network requests.
Step 7: Delete Data and Update the UI
The final piece of our app is allowing users to delete posts. This involves executing a delete_posts_by_pk mutation and updating the UI to reflect the change.
First we define the mutation:
const DELETE_POST = gql mutation DeletePost($id: uuid!) { delete_posts_by_pk(id: $id) { id title body createdAt } }
;
Then we call the generated mutation function:
function DeleteButton({ postId }) {
const [deletePost] = useMutation(DELETE_POST);
return (
<button onClick={() => {
if (window.confirm(‘Are you sure?‘)) {
deletePost({ variables: { id: postId } });
}
}}>
Delete
);
}
After the post is deleted on the server, we need to update our UI to remove the deleted item. Apollo Client‘s caching layer automatically updates the cache after mutations, but sometimes you need to refresh queries to update the UI.
The useMutation hook accepts a refetchQueries option that lets you specify which queries to re-run after the mutation executes. We can use this to refetch the list of posts after deleting an item:
useMutation(DELETE_POST, {
refetchQueries: [{ query: GET_POSTS }]
});
And with that, we have a fully-functioning social blogging app powered by React and GraphQL!
Wrapping Up
In this crash course, you learned how to:
- Create a GraphQL API with Hasura
- Write GraphQL queries and mutations
- Integrate a GraphQL API with React using Apollo Client
- Fetch and render data with the useQuery hook
- Create, update, and delete records with the useMutation hook
- Handle asynchronous states like loading and error
- Update the UI after mutations by refetching queries
These skills form the foundation for building modern, data-driven applications with React and GraphQL. I hope you enjoyed the course and are eager to apply these concepts to your own projects!
Next Steps
If you want to go deeper into React and GraphQL, I recommend checking out these resources:
- The official Apollo Client documentation: https://www.apollographql.com/docs/react/
- The React + GraphQL Tutorial on How to GraphQL: https://www.howtographql.com/react-apollo/0-introduction/
- The GraphQL Guide on the Apollo blog: https://www.apollographql.com/blog/graphql/basics/graphql-explained/
- The Full-Stack React + GraphQL Tutorial on the Apollo blog: https://www.apollographql.com/blog/full-stack-react-graphql-tutorial-582ac8d24e3b/
And if you want to master React and GraphQL, be sure to check out The React Bootcamp, my comprehensive video course that covers everything from the fundamentals to advanced topics like server-side rendering, testing, and GraphQL. You‘ll learn how to build real-world applications from scratch and level up your skills to become a professional React developer.
Thanks for following along, and happy coding!