在Apollo应用程序(还有GraphQL / Relay)中,可以选择将数据需求集中到组件,或者最终自己组装大型GraphQL查询。我们选择将数据需求与组件共存,因为我们希望在长时间内具有更好的可维护性,因为您不需要查看整个组件树或页面以查看所有数据要求,并且可以在本地添加新要求
我想更好地了解如何使用Apollo客户端编写GraphQL片段。我知道该怎么做,但我想知道如何才能做得更好。
目前,编写我的片段涉及相当多的样板文件,特别是当我的组件只是传递未触及的属性时。
首先,让我们来看一个简单的组件:
export const User = ({
user: {
firstName,
lastName,
job,
email,
pictureUrl,
color
},
...props
}) => (
<UserWrapper {...props}>
<UserAvatarWrapper>
<Avatar
firstName={firstName}
lastName={lastName}
color={color}
src={pictureUrl}
/>
</UserAvatarWrapper>
<UserContentWrapper>
{(firstName || lastName) &&
<UserName>
{firstName}
{" "}
{lastName}
{" "}
{email && <UserEmailInline>{email}</UserEmailInline>}
</UserName>}
{job && <UserJob>{job}</UserJob>}
</UserContentWrapper>
</UserWrapper>
);
User.fragments = {
user: gql`
fragment User on User {
id
firstName
lastName
pictureUrl: avatar
job
color
email
}
`,
};
以下是一些选择。似乎在大多数示例中都使用了某种约定,但此约定在文档中并不明确。
User.fragments
上使用的密钥。将它命名为与组件的propName user
完全相同是否有意义?
片段的名称:按照惯例,人们会将其命名为组件名称,如果有用,则以片段的GraphQL类型为后缀。 (这里UserUser
可能是矫枉过正的后缀)。
我认为在同一个应用程序中遵循相同的约定是很好的,因此所有片段声明都是一致的。那么,更有经验的人可以帮我澄清这个似乎在许多Apollo例子中使用过的约定吗?
让我们按照我们设定的惯例考虑Relationship
组件。
const Relationship = ({ user1, user2 }) => (
<RelationshipContainer>
<RelationshipUserContainer>
<User user={user1} />
</RelationshipUserContainer/>
<RelationshipUserContainer>
<User user={user2} />
</RelationshipUserContainer/>
</RelationshipContainer>
);
Relationship.fragments = {
user1: gql`
fragment RelationshipUser1User on User {
...User
}
${User.fragments.user}
`,
user2: gql`
fragment RelationshipUser2User on User {
...User
}
${User.fragments.user}
`,
};
请注意,我在这里声明了两个看起来相同的片段。我认为这是必要的,因为有两个道具,你不应该认为两个道具上的数据要求是相同的。我们可以很容易地想象一个包含me
道具和friend
道具的组件,您可以在其中收到me
道具的更多数据。
这很好用但很多样板和中间片段看起来很不必要。此外,它并不总是方便,因为从组件用户的角度来看,您必须知道2个片段名称才能使用它。
我尝试使用以下
简化此操作Relationship.fragments = {
user1: User.fragments.user,
user2: User.fragments.user,
};
这可以工作,但如果你这样做,那么片段名称不再是RelationshipUserXUser
,而是User
,这意味着它打破了封装,并且你需要在某种程度上意识到内部,Relationship
组件正在使用User
组件。
如果有一天,Relationship
组件切换到使用UserAlt
之类的替代表示,则需要使用关系片段从所有组件进行重构,这是我想要避免的。我认为在这种情况下,修改应该只在Relationship
组件中进行。
我想知道用Apollo组成碎片的最佳实践,以便组件保持真正的封装,最好不要涉及太多的样板。
我已经做对了吗?
如果我真的想撰写查询,是否所有这些样板都不可避免?
答案 0 :(得分:3)
这样做怎么样:
const userFragment = gql`
fragment Relationship_user on User {
...User_user
}
${User.fragments.user}
`;
Relationship.fragments = {
user1: userFragment,
user2: userFragment,
};
除此之外,我建议您按照上面的说明对片段名称进行定位,因为需要某种名称间距,否则您更有可能遇到使用相同的名称间距片段名称两次。
即。
User.fragments.user
=&gt; User_user
Relationship.fragments.user
=&gt; Relationship_user