Don*_*and 7 apollo reactjs graphql react-apollo
我正在使用Apollo Client和React,并且正在寻找一种策略,以使组件和组件数据需求并置在一起,以便可能需要查询和变异的父/兄弟/子组件可以访问它。我希望能够轻松地更新数据要求,这又将更新由某些父组件查询或由父/兄弟/子中的突变返回的字段,以便准确地更新我的Apollo缓存。
我尝试创建一个全局高级graphql目录,所有查询/mutations.graphql文件都位于该目录中,#导入整个应用程序中所有相关的片段文件,然后直接导入这些文件,但这会很乏味并且不会遵循父/子主题,其中父查询包括子片段。同样在大型项目中,导入时最终会遍历长文件路径。
我还尝试过仅在与组件文件相对应的全局graphql目录中共存片段文件,但这并不能为我提供所需的“组件/数据需求”共存。
这有效:
class CommentListItem extends Component {
static fragments = {
comment: gql`
#...
`,
}
}
class CommentList extends Component {
static fragments = {
comment: gql`
#...
${CommentListItem.fragments.comment}
`,
}
}
class CommentsPage extends Component {
static fragments = {
comment: gql`
#...
${CommentList.fragments.comment}
`,
}
}
graphql(gql`
query Comments {
comments {
...CommentsListItemComment
}
}
${CommentsPage.fragments.comment}
`)
Run Code Online (Sandbox Code Playgroud)
但是,如果我想要后代的突变,CommentsPage则不能引用的片段组成CommentsPage.fragments.comment。
对于这种事情,是否有首选的方法或最佳实践?
如何构造代码始终是个人喜好的问题,但我认为查询和组件的组合是GraphQL的一大优势。
对于查询,我从Relay Modern中获得了很多启发,该解决方案看起来与您在代码中描述的非常接近。现在,随着项目的扩大,我们希望为查询生成Flow类型定义,将它们放入组件文件旁边的单独文件中也是一种选择。这将非常类似于CSS-modules。
当涉及突变时,通常很难为它们找到合适的位置。需要在组件树远处的事件上调用突变,并且通常会在应用程序的多个状态下更改应用程序的状态。在这种情况下,您希望呼叫者不知道数据使用者。使用片段似乎是一个简单的答案。突变将只包括为特定类型定义的所有片段。现在,虽然突变不需要知道需要哪些字段,但是却需要知道谁需要类型上的字段。我想指出两种可以用于设计的略有不同的方法。
在中继中,现代变异基本上是全局操作,可以由任何组件触发。这种方法还不错,因为大多数变异只写一次,而且由于变量是非常可重用的。它们在一种全局状态下运行,并且不关心哪个UI部分使用了更新。定义突变结果时,通常应查询可能因突变而改变的属性,而不是其他组件(通过片段)所需的所有属性。例如,突变likeComment(id: ID!)可能应该在注释中查询likeCountand likes字段,而不在乎是否有任何组件完全使用了该字段或组件需要在其他字段上使用什么Comment。当您必须更新其他查询或字段时,此方法会变得更加困难。变异createComment(comment: CreateCommentInput)可能要写入根查询对象的comments字段。这是节点和边缘的中继结构派上用场的地方。您可以在此处了解有关中继更新的更多信息。
# A reusable likeComment mutation
mutation likeComment($id: ID!) {
likeComment(id: $id) {
comment {
id
likeCount
likes {
id
liker {
id
name
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我们无法回答一个问题:我们应该走多远?我是否需要喜欢评论的人员的姓名,或者该组件仅显示一些点赞?
并非所有的GraphQL API都是中继方式。此外,类似于Redux动作创建者,Apollo将突变绑定到商店。我当前的方法是使变异与查询处于同一级别,然后将其传递给下级。这样,您可以访问孩子的片段,并在需要时在突变中使用它们。在您的示例中,CommentListItem组件可能显示一个“赞”按钮。它将为数据依赖项定义一个片段,根据该片段定义prop类型,并定义一个函数prop type likeComment: (id: string) => Promise<any>。该prop类型将传递给查询容器,该容器将CommentsPagein 包装在查询和变异中。
您可以在Apollo中使用这两种方法。全局mutations文件夹可以包含可以在任何地方使用的突变。然后,您可以将突变直接绑定到需要它们的组件。一个好处是,例如,在likeComment可变例如id可以从部件道具直接导出,并不需要在组件本身内的约束。或者,您可以从查询组件传递突变。这使您可以更全面地了解数据使用者。在这种CommentsPage情况下,更容易决定突变完成后需要更新的内容。
让我知道您在评论中的想法!