跳至主要內容
支持烏克蘭 🇺🇦 協助向烏克蘭提供人道援助.

Relay可隨著您擴展的 GraphQL 客戶端。

為擴展而建構

Relay 的設計著重於在任何規模下實現高效能。無論您的應用程式有數十、數百還是數千個元件,Relay 都能輕鬆管理資料擷取。此外,歸功於 Relay 的增量編譯器,即使您的應用程式不斷成長,也能保持快速的迭代速度。

保持快速迭代

Relay 將資料擷取轉為宣告式。元件宣告其資料依賴性,而無需擔心如何擷取這些資料。Relay 保證會擷取每個元件所需的資料並使其可用。這能使元件保持解耦並促進重複使用。

透過 Relay,您可以快速修改元件及其資料依賴性,而無需修改系統的其他部分。這表示在重構或變更應用程式時,您不會意外中斷其他元件。

自動最佳化

Relay 的編譯器會彙總並最佳化整個應用程式的資料需求,以便可以在單一 GraphQL 請求中有效擷取這些資料。

Relay 會處理繁瑣的工作,以確保以最有效的方式擷取元件宣告的資料。例如,重複資料欄位的去重複化,以及預先計算執行階段使用的資訊,以及其他最佳化。

資料一致性

當影響元件的資料變更時,Relay 會自動更新所有元件,並僅在絕對必要時才有效更新元件。這表示不會進行不必要的重新渲染。

Relay 也支援執行 GraphQL 變更,可選擇執行樂觀更新,並更新本機資料,同時確保螢幕上的可見資料始終保持最新狀態。

擷取查詢資料

擷取查詢資料的最簡單方式是直接呼叫 loadQuery.

稍後,您可以透過呼叫 usePreloadedQuery Hook,在函式型 React 元件中從存放區讀取資料。

Relay 鼓勵您回應事件時呼叫 loadQuery,例如使用者按下連結以瀏覽至特定頁面或按下按鈕時。如需更多資訊,請參閱 查詢 的導覽章節。


import React from "react";
import { graphql, usePreloadedQuery, /* ... */ } from "react-relay";

const artistsQuery = graphql`
  query ArtistQuery($artistID: String!) {
    artist(id: $artistID) {
      name
      ...ArtistDescription_artist
    }
  }
`;
const artistsQueryReference = loadQuery(
  environment,
  artistsQuery,
  {artistID: "1"}
);

export default function ArtistPage() {
  return (
    <EnvironmentProvider environment={environment}>
      <React.Suspense fallback={<LoadingIndicator />}>
        <ArtistView />
      </React.Suspense>
    </EnvironmentProvider>
  )
}

function ArtistView() {
  const data = usePreloadedQuery(artistsQuery, artistsQueryReference);
  return (
    <>
      <Name>{data?.artist?.name}</Name>
      {data?.artist && <ArtistCard artist={data?.artist} />}
    </>
  );
}

片段

第二步是渲染由 Relay 驅動的 React 元件樹狀結構。元件使用片段宣告其資料依賴性,並透過呼叫從 Relay 存放區讀取資料 useFragment.

片段是連結到 GraphQL 類型 (例如 Artist) 的 GraphQL 程式碼片段,並指定從該類型的項目讀取哪些資料。

useFragment 採用兩個參數:片段字面值和片段參考。片段參考指定 要從哪個實體讀取該資料。

片段無法自行擷取;而是必須最終包含在父查詢中。接著,Relay 編譯器將確保在此類片段中宣告的資料依賴性會作為該父查詢的一部分擷取。


import React from "react";
import { graphql, useFragment} from "react-relay";

export default function ArtistCard(props) {
  const {href, image, bio} = useFragment(
    graphql`
      fragment ArtistHeader_artist on Artist {
        href
        bio
        image {
          url
        }
      }
    `,
    props.artist
  );
  const imageUrl = image && image.url;

  return (
    <Card>
      <Link href={href}>
        <Image imageUrl={imageUrl} />
        <Bio>{bio}</Bio>
      </Link>
    </Card>
  );
}
                    

內建的 GraphQL 最佳實務

Relay 會套用並依賴 GraphQL 最佳實務。若要充分利用 Relay 的功能,您會希望 GraphQL 伺服器符合這些標準實務。

片段

GraphQL 片段 是針對特定 GraphQL 類型的可重複使用欄位選取。您可以透過將其包含在其他片段中,或將其作為 GraphQL 查詢的一部分來組合此選取。

Relay 使用片段宣告元件的資料需求,並將資料需求組合在一起。

請參閱導覽

連線

GraphQL 連線 是 GraphQL 中用於表示資料清單的模型,以便能夠輕鬆地在任何方向進行分頁,並能夠編碼豐富的關聯資料。

GraphQL 連線被視為 GraphQL 分頁的最佳實務,只要您的 GraphQL 伺服器支援這些連線,Relay 就會為這些連線提供一流的支援。

請參閱 連線 文件

全域物件識別

Relay 依賴 全域物件識別 來提供可靠的快取和重新擷取,並讓您能夠自動合併物件的更新。

全域物件識別包含為每一個類型在整個結構描述中提供全域唯一 ID,這些 ID 是使用 Node GraphQL 介面建立的。

請參閱物件識別文件

彈性變更

說明資料變更

透過 GraphQL 變更,您可以宣告式地定義和請求執行變更會影響的資料 (在單次往返中),而 Relay 會自動合併並傳播這些變更。

自動更新

透過全域物件識別,Relay 能夠自動合併任何受影響物件的變更更新,並且僅更新受影響的元件。

對於無法自動合併更新的更複雜案例,Relay 提供 API 以便在回應變更時手動更新本機 Relay 資料。

專為出色的使用者體驗設計

Relay 的變更 API 支援進行樂觀更新,以便向使用者顯示即時回饋,以及錯誤處理和在變更失敗時自動還原變更。

提前安全

安心無虞

當您在 Relay 專案上工作時,Relay 編譯器會引導您,以確保整個專案在 GraphQL 結構描述中保持一致性和正確性。

最佳化執行階段

Relay 會提前在建置階段預先計算許多工作 (例如處理和最佳化查詢),以便盡可能提高瀏覽器或裝置上的執行階段效率。

類型安全

Relay 會為每個使用 Relay 的 React 元件產生 Flow 或 TypeScript 類型,這些類型代表每個元件接收的資料,因此您可以在確保正確性的情況下,更快且更安全地進行變更。

Relay 適合我嗎?

逐步採用

如果您已經可以渲染 React 元件,則您已完成大部分工作。Relay 需要 Babel 外掛程式,並且也需要執行 Relay 編譯器。

您可以立即在 Create React App 和 Next.js 中使用 Relay。

明確指出複雜性

Relay 需要更多的前期設定和工具,以便支援獨立元件的架構,這些元件可隨著您的團隊和應用程式複雜性擴展。

一次學習這些原則,然後將更多時間投入到商業邏輯中,而不是資料管道傳輸。

在 Facebook 規模中使用

Relay 是 Facebook 中的重要基礎結構,有數萬個元件使用它。Relay 是與 GraphQL 同時建構的,並有專職人員致力於改進它。

不僅適用於大型應用程式

如果您是那種相信使用 Flow 或 TypeScript 來將錯誤偵測移至開發階段的團隊,那麼 Relay 很可能適合您。

否則您可能會獨立重新建立許多 Relay 的快取和 UI 最佳實務。