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

陣列與列表

到目前為止,我們只處理了組件中只有單個實例的組件。例如,我們只顯示單個新聞提要故事,並且在該故事中,只有一個具有單個個人資料圖片的作者。讓我們看看如何處理多個相同的事物。

GraphQL 包含對陣列的支援,在 GraphQL 中稱為列表。一個欄位不僅可以是單個純量值,還可以是它們的陣列,或者不僅是單個邊緣,還可以是邊緣的陣列。Schema 指定每個欄位是否為列表,但奇怪的是,GraphQL 查詢語法並不區分選擇單個欄位和選擇列表 - 這是 GraphQL 回應應該與查詢具有相同形狀的設計原則的一個奇怪例外。

請求

query MyQuery {
viewer {
contacts { // List of edges
id // field on a single item
name
}
}
}

回應

{
viewer: {
contacts: [ // array in response
{
id: "123",
name: "Chris",
},
{
id: "789",
name: "Sue",
}
]
}
}

碰巧的是,我們的範例應用程式中的 schema 有一個 topStories 欄位,該欄位返回故事列表,而不是我們目前使用的僅返回一個故事的 topStory 欄位。

為了在我們的新聞提要上顯示多個故事,我們只需要修改 Newsfeed.tsx 以使用 topStories

步驟 1 — 在片段中選擇列表

打開 Newsfeed.tsx 並找到 NewsfeedQuery。將 topStory 替換為 topStories,然後執行 npm run relay

const NewsfeedQuery = graphql`
query NewsfeedQuery {
topStories {
...StoryFragment
}
}
`;

步驟 2 — 在組件中映射列表

Newsfeed 組件中,data.topStories 現在將會是一個片段引用陣列,每個片段引用都可以傳遞給 Story 子組件以呈現該故事

export default function Newsfeed({}) {
const data = useLazyLoadQuery<NewsfeedQueryType>(NewsfeedQuery, {});
const stories = data.topStories;
return (
<div className="newsfeed">
{stories.map(story => <Story story={story} />)}
</div>
);
}

步驟 3 — 根據節點 ID 新增 React 金鑰

到目前為止,您應該在螢幕上看到多個故事了!它開始看起來像一個適當的新聞提要應用程式。

Multiple stories

但是,我們也收到一個 React 警告,警告我們正在呈現一個沒有提供 key 屬性的組件陣列。

React missing key warning

始終要注意這個警告,更具體來說,要根據顯示的事物的身分來建立金鑰,而不僅僅是它們在陣列中的索引。這允許 React 正確處理重新排序和從列表中刪除項目,因為它知道哪些項目是什麼,即使它們的順序發生變化。

幸運的是,GraphQL 節點通常具有 ID。我們可以簡單地選擇 storyid 欄位並將其用作金鑰

const NewsfeedQuery = graphql`
query NewsfeedQuery {
topStories {
id
...StoryFragment
}
}
`;

...

export default function Newsfeed({}) {
const data = useLazyLoadQuery<NewsfeedQueryType>(NewsfeedQuery, {});
const stories = data.topStories;
return (
<div className="newsfeed">
{stories.map(story => (
<Story
key={story.id}
story={story}
/>
)}
</div>
);
}

有了這個,我們在螢幕上就有了一系列故事。值得指出的是,在這裡我們在查詢的同一位置混合了個別欄位和片段展開。這表示 Newsfeed 可以讀取它關心的欄位(直接從 useLazyLoadQuery 讀取),而 Story 可以讀取它關心的欄位(透過 useFragment 讀取)。同一個物件同時包含 Newsfeed 的選定欄位 id,並且也是 StoryFragment 的片段金鑰。

提示

GraphQL 列表只是處理事物集合的最基本方式。我們稍後將在教學中使用它們來進行分頁和無限捲動,使用一個稱為「連接」的特殊系統。在大多數需要處理項目集合的情況下,您都應該使用「連接」,儘管您仍然會使用 GraphQL 列表作為基礎。

繼續前進!