跳至主要內容
版本:v18.0.0

變數

您可能已經注意到,我們上面範例中的查詢宣告包含對 GraphQL 程式碼內 $id 符號的引用:這些是GraphQL 變數

GraphQL 變數是一種結構,允許在 GraphQL 查詢中引用動態值。當從伺服器獲取查詢時,我們還需要提供輸入,用於查詢內宣告的變數的實際值集。

query UserQuery($id: ID!) {
# The value of $id is used as input to the user() call:
user(id: $id) {
id
name
}
}

在上面,ID!$id 變數的類型。也就是說,它是一個必要的 ID。

當傳送網路請求以獲取上述查詢時,我們需要同時提供查詢,以及用於查詢特定執行的變數。例如

# Query:
query UserQuery($id: ID!) {
# ...
}

# Variables:
{"id": 4}

從伺服器獲取上述查詢和變數會產生以下回應

{
"data": {
"user": {
"id": "4",
"name": "Mark Zuckerberg"
}
}
}

片段也可以引用查詢宣告的變數

fragment UserFragment on User {
name
profile_picture(scale: $scale) {
uri
}
}


query ViewerQuery($scale: Float!) {
viewer {
actor {
...UserFragment
}
}
}
  • 即使上面的片段沒有直接宣告 $scale 變數,它仍然可以引用它。這樣做會使得任何直接或遞迴包含此片段的查詢,必須宣告變數及其類型,否則將產生錯誤。
  • 換句話說,查詢變數在任何查詢的後代片段中都是全域可用的
  • 引用全域變數的片段只能包含(直接或遞迴)在定義該全域變數的查詢中。

在 Relay 中,元件內的片段宣告也可以引用查詢變數

function UserComponent(props: Props) {
const data = useFragment(
graphql`
fragment UserComponent_user on User {
name
profile_picture(scale: $scale) {
uri
}
}
`,
props.user,
);

return (...);
}
  • 上面的片段可以被多個查詢包含,並由不同的元件渲染,這表示任何最終渲染/包含上述片段的查詢,必須宣告 $scale 變數。
  • 如果任何包含此片段的查詢沒有宣告 $scale 變數,Relay 編譯器會在建置時產生錯誤,確保不正確的查詢永遠不會傳送到伺服器(傳送缺少變數宣告的查詢也會在伺服器中產生錯誤)。

@arguments 和 @argumentDefinitions

Relay 還提供一種方法來宣告在片段中使用 @arguments@argumentDefinitions 指令,將變數限定於片段的範圍內。使用局部變數的片段易於自訂和重複使用,因為它們不依賴於全域(查詢層級)變數的值。

/**
* Declare a fragment that accepts arguments with @argumentDefinitions
*/

function TaskView(props) {
const data = useFragment(
graphql`
fragment TaskView_task on Task
@argumentDefinitions(showDetailedResults: {type: "Boolean!"}) {
name
is_completed
... @include(if: $showDetailedResults) {
description
}
}
`,
props.task,
);
}
/**
* Include fragment using @arguments
*/

function TaskList(props) {
const data = usePreloadedQuery(
graphql`
query TaskListQuery {
todays_tasks {
...TaskView_task @arguments(showDetailedResults: true)
}
tomorrows_tasks {
...TaskView_task @arguments(showDetailedResults: false)
}
}
`,
props.queryRef,
);
}
  • 局部範圍的變數也使從另一個查詢重複使用片段更容易。

    • 查詢定義必須列出任何巢狀片段使用的所有變數,包括遞迴巢狀片段。

    • 由於片段可能會從許多查詢存取,修改使用全域變數的片段可能需要更改許多查詢定義。

    • 這也可能導致尷尬的情況,例如有多個版本的「相同」變數,例如 $showDetailedResults$showDetails

    • 由於僅具有局部範圍變數的片段不使用全域變數,因此它們不受此問題影響。

  • 請注意,當將 @arguments 傳遞給片段時,我們可以傳遞文字值或傳遞另一個變數。該變數可以是全域查詢變數、透過 @argumentDefinitions 宣告的局部變數或文字(例如 42.0)。

  • 當我們實際擷取 TaskView_task 作為查詢的一部分時,showDetailedResults 值將取決於 TaskView_task 的父層所提供的引數。

預期引數的片段也可以宣告預設值,使引數成為選擇性的

/**
* Declare a fragment that accepts arguments with default values
*/

function TaskView(props) {
const data = useFragment(
graphql`
fragment TaskView_task on Task
@argumentDefinitions(showDetailedResults: {type: "Boolean!", defaultValue: true}) {
name
is_completed
... @include(if: $showDetailedResults) {
description
}
}
`,
props.task,
);
}
function TaskList(props) {
const data = usePreloadedQuery(
graphql`
query TaskListQuery {
todays_tasks {
...TaskView_task
}
tomorrows_tasks {
...TaskView_task @arguments(showDetailedResults: false)
}
}
`,
props.queryRef,
);
}
  • 不將引數傳遞給 TaskView_task 會使其使用其局部宣告的 $showDetailedResult 變數的預設值。

在執行階段存取 GraphQL 變數

如果您想存取在查詢根目錄設定的變數,建議的方法是使用屬性或您自己的應用程式特定內容,將變數傳遞到應用程式的元件樹中。

Relay 目前不公開特定片段的已解析變數(即,在應用引數定義之後),並且您應該很少需要這樣做。


此頁面是否有用?

請透過以下方式幫助我們使網站更好 回答幾個快速問題.