Revere Cre กำลังจ้าง! สนใจที่จะทำงานเกี่ยวกับขอบด้านหน้าของส่วนหน้าหรือไม่?
ติดต่อ [email protected] สำหรับข้อมูลเพิ่มเติม
เอกสาร การอภิปราย | รุ่นล่าสุด
relay-nextjs เป็นวิธีที่ดีที่สุดในการใช้ Relay และ Next.js ในโครงการเดียวกัน! รองรับ การโยกย้ายที่เพิ่มขึ้น พร้อมความพร้อม และ ดำเนินการ โดย บริษัท ยักษ์ใหญ่
relay-nextjs wraps ส่วนประกอบหน้า, การสืบค้น GraphQL และวิธีการช่วยบางอย่างเพื่อเชื่อมต่อข้อมูลโดยอัตโนมัติโดยใช้รีเลย์ ในการโหลดเริ่มต้นสภาพแวดล้อมการถ่ายทอดจะถูกสร้างขึ้นข้อมูลจะถูกดึงไปด้านเซิร์ฟเวอร์หน้าจะแสดงผลและสถานะผลลัพธ์จะถูกทำให้เป็นอนุกรมเป็นแท็กสคริปต์ ในการบูตในไคลเอนต์สภาพแวดล้อมการถ่ายทอดใหม่และแบบสอบถามที่โหลดไว้ล่วงหน้าถูกสร้างขึ้นโดยใช้สถานะอนุกรมนั้น ข้อมูลจะถูกดึงโดยใช้สภาพแวดล้อมรีเลย์ฝั่งไคลเอ็นต์ในการนำทางที่ตามมา
หมายเหตุ: relay-nextjs ไม่รองรับเราเตอร์แอป NextJS 13 ในขณะนี้
ติดตั้งโดยใช้ NPM หรือตัวจัดการแพ็คเกจที่คุณชื่นชอบอื่น ๆ :
$ npm install relay-nextjs relay-nextjs จะต้องกำหนดค่าใน _app เพื่อสกัดกั้นและจัดการการกำหนดเส้นทางอย่างถูกต้อง
สำหรับข้อมูลพื้นฐานเกี่ยวกับสภาพแวดล้อมการถ่ายทอดโปรดดูเอกสารการถ่ายทอด
relay-nextjs ได้รับการออกแบบโดยคำนึงถึงการแสดงผลทั้งฝั่งไคลเอ็นต์และฝั่งเซิร์ฟเวอร์ ดังนั้นจึงจำเป็นต้องสามารถใช้สภาพแวดล้อมการถ่ายทอดฝั่งไคลเอ็นต์หรือฝั่งเซิร์ฟเวอร์ ห้องสมุดรู้วิธีจัดการกับสภาพแวดล้อมที่จะใช้ แต่เราต้องบอกวิธีการสร้างสภาพแวดล้อมเหล่านี้ สำหรับสิ่งนี้เราจะกำหนดสองฟังก์ชั่น: getClientEnvironment และ createServerEnvironment หมายเหตุความแตกต่าง-บนไคลเอนต์มีเพียงสภาพแวดล้อมเดียวเท่านั้นที่สร้างขึ้นเนื่องจากมีเพียงแอพเดียว แต่บนเซิร์ฟเวอร์เราต้องสร้างสภาพแวดล้อมต่อการเรนเดอร์เพื่อให้แน่ใจว่าแคชไม่ได้แชร์ระหว่างคำขอ
ก่อนอื่นเราจะกำหนด 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 ;
} จากนั้น 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 ,
} ) ;
}หมายเหตุในสภาพแวดล้อมเซิร์ฟเวอร์ตัวอย่างเรากำลังดำเนินการกับสคีมาในท้องถิ่น แต่คุณอาจดึงข้อมูลจาก API ระยะไกลได้เช่นกัน
_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 ) ;
} ,
} ) ;