Skip to content

ServerlessReact.dev

Student Login
  • Welcome to the workshop
Before the workshop
The workshop
Before you head out

Dynamic data in the browser

In the browser, your JAMStack app becomes a typical React app and loading data is a common operation.

You're going to learn the declarative query approach to data loading. Both for GraphQL and REST.

In the interest of time, we're doing these exercises with Gatsby. You can use the same approach with NextJS.

GraphQL with Apollo Client

GraphQL creates a flexible interface to your data. It moves flexibility (and complexity) to the frontend so you can iterate faster.

Apollo Client is the most popular GraphQL client and the library that popularized declarative queries. Comes with built-in query caching and request optimizations.

Exercise

Continue with your Gatsby project from before, or jump into mine in exercise-4. Use the SpaceX GraphQL API create a page that lists SpaceX's last 10 launches.

As always with Gatsby, there's a plugin for this.

Install gatsby-plugin-apollo and @apollo/client and enable the plugin in gatsby-config.js:

// gatsby-config.js
{
resolve: 'gatsby-plugin-apollo',
options: {
uri: 'https://api.spacex.land/graphql'
}
}

You can now query the SpaceX API in any React component with the useQuery hook. I suggest making a self-contained <LaunchList> component. Something like this:

import { gql, useQuery } from "@apollo/client"
export const LaunchList = () => {
const { loading, error, data } = useQuery(gql`
{
launchesPast(limit: 10) {
mission_name
links {
article_link
video_link
}
rocket {
rocket_name
}
}
}
`)
if (loading) {
// indicate loading state
} else if (error) {
// show an error
} else {
// list launches, they're in data.launchesPast
}
}

PS: for NextJS, you'll have to wrap _app.js in <ApolloProvider> yourself becuse there's no plugin. The rest stays the same.

Solution

Find mine in the exercise-4-solution branch.

REST with React Query

React Query took the idea of declarative queries from GraphQL and applied it to REST. Comes with many of the same benefits like caching and optimization.

Unlike GraphQL, React Query can't understand your queries, which means it can't optimize at the request fragment level.

Exercise

Use the SpaceX REST API to create a page that lists SpaceX's last 10 launches.

There's no Gatsby plugin for React Query. You'll have to set it up yourself.

Install react-query and wrap your component root in the cache provider. Add it to both gatsby-browser.js and gatsby-ssr.js.

import { QueryCache, ReactQueryCacheProvider } from "react-query"
const queryCache = new QueryCache()
export const wrapRootElement = ({ element }) => {
return (
<ReactQueryCacheProvider queryCache={queryCache}>
{element}
</ReactQueryCacheProvider>
)
}

You can now query REST APIs from anywhere with the useQuery hook. I recommend creating a new LaunchListREST component. Like this:

import { useQuery } from "react-query"
export const LaunchListREST = () => {
const { isLoading, error, data } = useQuery(["launches-past"], async () => {
const res = await fetch(
"https://api.spacex.land/rest/launches-past?limit=10"
)
return res.json()
})
if (loading) {
// indicate loading state
} else if (error) {
// show an error
} else {
// list launches, they're in data
}
}

Look at your network log, see the difference in how much data you load with GraphQL vs. REST.

Solution

Find mine in the exercise-4-solution branch.

Wormhole state management

The core benefit of the declarative query approach to data loading is that performance is solved for you. Run the query wherever you need data, don't worry about repeat requests.

Exercise

Take your launches page and add a button that renders a new <LaunchList> and <LaunchListREST> component on the same page. See what happens in your network tab.

Now add a staleness timeout to your REST query and try again.

{
staleTime: 5 * 60 * 1000,
}

Solution

Find mine in the exercise-4-solution branch.

Did you enjoy this chapter?

Previous:
Markdown and MDX for content
Next:
Baked-in static data
Created bySwizecwith ❤️