Revere Cre embauche! Intéressé à travailler sur la pointe du frontend?
Contactez la main à [email protected] pour plus d'informations.
Documentation | Discussion | Dernières versions
relay-nextjs est le meilleur moyen d'utiliser Relay et Next.js dans le même projet! Il soutient la migration supplémentaire , est prête à suspense et est gérée en production par les grandes entreprises.
relay-nextjs Enveloppe les composants de la page, une requête GraphQL et certaines méthodes d'assistance pour connecter automatiquement la récupération des données à l'aide du relais. Dans un environnement de chargement initial, un environnement de relais est créé, les données sont récupérées côté serveur, la page est rendue et l'état résultant est sérialisé en tant que balise de script. Sur Boot in the Client, un nouvel environnement de relais et une requête préchargée sont créées en utilisant cet état sérialisé. Les données sont récupérées à l'aide de l'environnement de relais côté client lors des navigations ultérieures.
Remarque: relay-nextjs ne prend pas en charge le routeur de l'application NextJS 13 pour le moment.
Installez à l'aide de NPM ou de votre autre gestionnaire de packages préféré:
$ npm install relay-nextjs relay-nextjs doit être configuré dans _app pour intercepter et gérer correctement le routage.
Pour des informations de base sur l'environnement de relais, veuillez consulter les documents de relais.
relay-nextjs a été conçu avec le rendu côté client et côté serveur à l'esprit. En tant que tel, il doit être en mesure d'utiliser un environnement de relais côté client ou côté serveur. La bibliothèque sait comment gérer le environnement à utiliser, mais nous devons lui dire comment créer ces environnements. Pour cela, nous définirons deux fonctions: getClientEnvironment et createServerEnvironment . Remarquez la distinction - sur le client, un seul environnement est créé car il n'y a qu'une seule application, mais sur le serveur, nous devons créer un environnement par rapport pour s'assurer que le cache n'est pas partagé entre les demandes.
Nous allons d'abord définir getClientEnvironment :
// lib/client_environment.ts
import { Environment , Network , Store , RecordSource } from 'relay-runtime' ;
export function createClientNetwork ( ) {
return Network . create ( async ( params , variables ) => {
const response = await fetch ( '/api/graphql' , {
method : 'POST' ,
credentials : 'include' ,
headers : {
'Content-Type' : 'application/json' ,
} ,
body : JSON . stringify ( {
query : params . text ,
variables ,
} ) ,
} ) ;
const json = await response . text ( ) ;
return JSON . parse ( json ) ;
} ) ;
}
let clientEnv : Environment | undefined ;
export function getClientEnvironment ( ) {
if ( typeof window === 'undefined' ) return null ;
if ( clientEnv == null ) {
clientEnv = new Environment ( {
network : createClientNetwork ( ) ,
store : new Store ( new RecordSource ( ) ) ,
isServer : false ,
} ) ;
}
return clientEnv ;
} Et puis createServerEnvironment :
import { graphql } from 'graphql' ;
import { GraphQLResponse , Network } from 'relay-runtime' ;
import { schema } from 'lib/schema' ;
export function createServerNetwork ( ) {
return Network . create ( async ( text , variables ) => {
const context = {
token ,
// More context variables here
} ;
const results = await graphql ( {
schema ,
source : text . text ! ,
variableValues : variables ,
contextValue : context ,
} ) ;
return JSON . parse ( JSON . stringify ( results ) ) as GraphQLResponse ;
} ) ;
}
export function createServerEnvironment ( ) {
return new Environment ( {
network : createServerNetwork ( ) ,
store : new Store ( new RecordSource ( ) ) ,
isServer : true ,
} ) ;
}Remarque dans l'exemple de l'environnement du serveur que nous exécutons sur un schéma local, mais vous pouvez également aller à partir d'une API distante.
_app // pages/_app.tsx
import { RelayEnvironmentProvider } from 'react-relay/hooks' ;
import { useRelayNextjs } from 'relay-nextjs/app' ;
import { getClientEnvironment } from '../lib/client_environment' ;
function MyApp ( { Component , pageProps } : AppProps ) {
const { env , ... relayProps } = useRelayNextjs ( pageProps , {
createClientEnvironment : ( ) => getClientSideEnvironment ( ) ! ,
} ) ;
return (
< >
< RelayEnvironmentProvider environment = { env } >
< Component { ... pageProps } { ... relayProps } />
</ RelayEnvironmentProvider >
</ >
) ;
}
export default MyApp ; // src/pages/user/[uuid].tsx
import { withRelay , RelayProps } from 'relay-nextjs' ;
import { graphql , usePreloadedQuery } from 'react-relay/hooks' ;
// The $uuid variable is injected automatically from the route.
const ProfileQuery = graphql `
query profile_ProfileQuery($uuid: ID!) {
user(id: $uuid) {
id
firstName
lastName
}
}
` ;
function UserProfile ( { preloadedQuery } : RelayProps < { } , profile_ProfileQuery > ) {
const query = usePreloadedQuery ( ProfileQuery , preloadedQuery ) ;
return (
< div >
Hello { query . user . firstName } { query . user . lastName }
</ div >
) ;
}
function Loading ( ) {
return < div > Loading... </ div > ;
}
export default withRelay ( UserProfile , UserProfileQuery , {
// Fallback to render while the page is loading.
// This property is optional.
fallback : < Loading /> ,
// Create a Relay environment on the client-side.
// Note: This function must always return the same value.
createClientEnvironment : ( ) => getClientEnvironment ( ) ! ,
// variablesFromContext allows you to declare and customize variables for the graphql query.
// by default variablesFromContext is ctx.query
variablesFromContext : ( ctx : NextRouter | NextPageContext ) => ( { ... ctx . query , otherVariable : true } ) ,
// Gets server side props for the page.
serverSideProps : async ( ctx ) => {
// This is an example of getting an auth token from the request context.
// If you don't need to authenticate users this can be removed and return an
// empty object instead.
const { getTokenFromCtx } = await import ( 'lib/server/auth' ) ;
const token = await getTokenFromCtx ( ctx ) ;
if ( token == null ) {
return {
redirect : { destination : '/login' , permanent : false } ,
} ;
}
return { token } ;
} ,
// Server-side props can be accessed as the second argument
// to this function.
createServerEnvironment : async (
ctx ,
// The object returned from serverSideProps. If you don't need a token
// you can remove this argument.
{ token } : { token : string }
) => {
const { createServerEnvironment } = await import ( 'lib/server_environment' ) ;
return createServerEnvironment ( token ) ;
} ,
} ) ;