¡Revere Cre está contratando! ¿Interesado en trabajar en la vanguardia de Frontend?
Comuníquese con [email protected] para obtener más información.
Documentación | Discusión | Últimos lanzamientos
relay-nextjs es la mejor manera de usar Relay y Next.js en el mismo proyecto! Apoya la migración incremental , está listo para el suspenso y está en producción por las principales empresas.
relay-nextjs envuelve los componentes de la página, una consulta GraphQL y algunos métodos auxiliares para conectar automáticamente la obtención de datos utilizando Relay. En la carga inicial se crea un entorno de retransmisión, los datos se obtienen del lado del servidor, la página se representa y el estado resultante se está serializado como una etiqueta de script. En el arranque en el cliente, se crean un nuevo entorno de retransmisión y una consulta precargada utilizando ese estado serializado. Los datos se obtienen utilizando el entorno de retransmisión del lado del cliente en las navegaciones posteriores.
Nota: relay-nextjs no admite el enrutador de aplicaciones NextJS 13 en este momento.
Instalar con NPM o su otro administrador de paquetes favorito:
$ npm install relay-nextjs relay-nextjs debe configurarse en _app para interceptar correctamente y manejar el enrutamiento.
Para obtener información básica sobre el entorno de retransmisión, consulte los documentos de retransmisión.
relay-nextjs fue diseñado con la representación del lado del cliente y del lado del servidor en mente. Como tal, debe poder usar un entorno de retransmisión del lado del cliente o del lado del cliente. La biblioteca sabe cómo manejar qué entorno usar, pero tenemos que decirle cómo crear estos entornos. Para esto definiremos dos funciones: getClientEnvironment y createServerEnvironment . Tenga en cuenta la distinción: en el cliente, solo se crea un entorno porque solo hay una aplicación, pero en el servidor debemos crear un entorno por renderizado para garantizar que el caché no se comparta entre las solicitudes.
Primero definiremos 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 ;
} Y luego 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 ,
} ) ;
}Tenga en cuenta que en el entorno del servidor de ejemplo estamos ejecutando con un esquema local, pero también puede obtener desde una API remota.
_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 ) ;
} ,
} ) ;