使用GraphQL片段掩码时,如何为React循环设置key属性?
解决Fragment Masking下React循环key的获取问题
以下是几种常见的可行方案:
方法1:扩展父查询字段,显式包含key所需内容
在父查询的node节点中,除了引用RepositoryCard片段,额外添加resourcePath字段;或者创建一个包含标识字段的共享片段,让父查询和子片段同时引用,这样父组件就能合法访问该字段:直接添加字段的查询示例:
query GetUserData($login: String!) { user(login: $login) { bio name repositories(first: 10) { edges { node { ...RepositoryCard resourcePath # 显式声明key所需字段 } } } } }共享片段的实现示例:
# 新建用于标识的共享片段 fragment RepositoryIdentifier on Repository { resourcePath } # 让原有卡片片段继承该标识片段 fragment RepositoryCard on Repository { ...RepositoryIdentifier description } # 父查询同时引用两个片段 query GetUserData($login: String!) { user(login: $login) { bio name repositories(first: 10) { edges { node { ...RepositoryCard ...RepositoryIdentifier } } } } }调整后父组件即可直接使用
repository.node.resourcePath作为循环的key。方法2:封装映射项为子组件,内部用useFragment读取字段
将循环中的每个卡片项抽成独立组件,在组件内部通过useFragment钩子读取片段字段,以此设置key,既保留Fragment Masking的类型安全,又无需修改父查询结构:import { useFragment } from '@apollo/client'; import { RepositoryCardFragmentDoc } from './generated/graphql'; const RepositoryCardItem = ({ node }) => { const repo = useFragment(RepositoryCardFragmentDoc, node); return <RepositoryCard className="my-2" repositoryNode={node} key={repo.resourcePath} />; }; // 父组件中调用映射 { data?.user?.repositories?.edges?.map((repository) => ( <RepositoryCardItem node={repository?.node} /> )) }方法3:利用GraphQL内置ID字段(如果可用)
若GitHub的Repository类型提供了id字段,可直接在父查询中请求该字段作为key,无需改动现有片段:query GetUserData($login: String!) { user(login: $login) { bio name repositories(first: 10) { edges { node { ...RepositoryCard id # 使用内置ID作为唯一标识 } } } } }随后在父组件中用
repository.node.id作为循环key即可。
内容的提问来源于stack exchange,提问作者Haf
相关产品推荐
相关产品推荐

