Relay is a JavaScript framework for building data-driven React applications.
- Declarative: Never again communicate with your data store using an imperative API. Simply declare your data requirements using GraphQL and let Relay figure out how and when to fetch your data.
- Colocation: Queries live next to the views that rely on them, so you can easily reason about your app. Relay aggregates queries into efficient network requests to fetch only what you need.
- Mutations: Relay lets you mutate data on the client and server using GraphQL mutations, and offers automatic data consistency, optimistic updates, and error handling.
Relay Hooks is the easiest-to-use, safest Relay API. It relies on suspense, and is safe to use in React concurrent mode.
Recommended reading: Thinking in Relay
This example demonstrates the two main strategies of optimised fetching data in a Next.js application using Relay Hooks:
- Page Data: using Next.js's props loading methods
getStaticProps()
,getServerSideProps()
, orgetInitialProps()
with Relay Hooks. - Lazy Data: using Next.js's
next/dynamic
lazy component import in parallel with Relay'suseQueryLoader()
for render-as-you-fetch data loading.
When using getStaticProps()
, getServerSideProps()
, or getInitialProps()
,
Next.js by default optimises network requests to fetch data + load JavaScript.
By leveraging Relay's compiler, we are able to combine deeply nested data
requirements into a single query executable within a get*Props()
method,
avoiding waterfalls and staggered data loads.
See pages/index.jsx
for an example of using
getStaticProps()
(the same code should work for getServerSideProps()
&
getInitialProps()
)
There are times when your application loads a page with portions purposely hidden until user interaction or some other event occurs. An example is expanding a complex portion of the UI that is not often used; a better user experience is achieved by delaying the loading & execution of JavaScript until the user explicitly requests it. In Next.js, this is achieved using dynamic imports.
To achieve optimised network requests for lazily (ie; dynamically) loaded
components, the data can be fetched in parallel using Relay's
useQueryLoader()
&
usePreloadedQuery()
,
triggered at the same time as the user triggers the component load (eg; clicking
"Expand" to show some complex UI).
The example in pages/films.jsx
builds on the concepts in
pages/index.jsx
using useQueryLoader()
, usePreloadedQuery()
, and
dynamic()
to optimise data & component loading to happen in parallel. Aka:
render-as-you-fetch.
Deploy the example using Vercel:
Execute create-next-app
with npm or Yarn to bootstrap the example:
npx create-next-app --example with-relay with-relay-app
# or
yarn create next-app --example with-relay with-relay-app
Download schema introspection data from configured Relay endpoint (this example uses the StarWars GraphQL API):
npm run schema
# or
yarn schema
Run Relay ahead-of-time compilation (should be re-run after any edits to components that query data with Relay):
npm run relay
# or
yarn relay
Run the project:
npm run dev
# or
yarn dev
Deploy it to the cloud with Vercel (Documentation).