使用 Apollo 的片段驅動 UI
我是 Relay 的忠實粉絲,但我一直對 Apollo 客戶端很好奇,所以最近我開始在一個新的副項目上學習它。我有過很好的體驗,但一個很大的不同是 Apollo 如何使用片段。
什麼是片段驅動的 UI?
片段驅動的 UI 讓我們可以在每個組件中聲明我們的數據,讓我們快速瀏覽組件所需的數據,減少道具鑽探並減少出錯的可能性。
這是 Relay 文檔中的一個簡單示例
type Props = {|
user: UserComponent_user$key,
|};
function UserComponent(props: Props) {
const data = useFragment(
graphql`
fragment UserComponent_user on User {
name
profile_picture(scale: 2) {
uri
}
}
`,
props.user,
);
return (
<>
<h1>{data.name}</h1>
<div>
<img src={data.profile_picture?.uri} />
</div>
</>
);
}
你可以很容易地看到組件需要的數據,而我們唯一需要做的就是滿足組件數據的要求,就是將 user key prop 傳下來。這是一個演示 UserComponent 的父組件的快速示例
type Props = {|
id: string,
|};
function UserPage({id}: Props) {
const data = useLazyLoadQuery(
graphql`
query User($id: ID!) {
user(id: $id) {
...UserComponent_user
}
}
`,
{id} ,
);
return (
<UserComponent user={data.user} />
);
}
無論您的組件需要多大的查詢,您總是只會為它傳遞一個道具。這有助於大型團隊更快、更輕鬆地行動。
搬到阿波羅
我正在使用 Typescript 以及 GraphQL 代碼生成器,這是我的 codegen.yml
overwrite: true
schema: 'http://localhost:4000/graphql'
documents: '{pages,components,graphql}/**/*.{ts,tsx}'
generates:
generated/graphqlComponents.tsx:
plugins:
- 'typescript'
- 'typescript-operations'
- 'typescript-react-apollo'
這將為頁面、組件或 graphql 文件夾上的 graphql 標籤生成 graphql 類型。
這是 Apollo 中的 Fragment UI 組件
type Props = {
data: UserAvatar_UserFragment;
};
const UserAvatar = ({ data }: Props) => {
return (
<Flex alignItems="center">
<Link href={`/u/${data.username}`}>
<a>
<Text fontWeight="700">
{data.username}
</Text>
</a>
</Link>
</Flex>
);
};
UserAvatar.USER_AVATAR_FRAGMENT = gql`
fragment UserAvatar_user on User {
username
}
`;
這與 Relay 非常相似,但我們不是將密鑰傳遞給片段引用,而是傳遞片段數據,這些數據將出現在我們的父組件中,這種數據類型來自我們的 GraphQL Code Gen。
const COLLECTION_QUERY = gql`
query Collection($id: ID!) {
collection(id: $id) {
user {
...UserAvatar_user
}
}
}
`;
const CollectionPage = () => {
const router = useRouter();
const { data } = useCollectionQuery({ variables: { id: router.query.id } });
return (
<UserAvatar data={data.collection.user} />
);
};
我們使用從 Code Gen 生成的 Query 鉤子,並將數據道具傳遞給我們的子組件。提供與 Relay 類似的開發體驗,同時還擁有來自 Apollo 的自由!
感謝您的閱讀,希望對您有用!如果您對 Relay 有任何疑問或想了解更多信息,請在下方評論!