3

我的父组件以嵌套片段结束,如下所示:

query MyAppQuery(
    $id
    $a
    $b
    $c
) {
    viewer {
      ...App_viewer
      ...ComponentA_viewer @include(if: $a)
      ...ComponentB_viewer @include(if: $b)
      ...ComponentC_viewer @include(if: $c)
    }
    allEmployees: allUsers(userType: "1") {
        ...ComponentA_allEmployees @include(if: $a)
        ...ComponentB_allEmployees @include(if: $b)
        ...ComponentC_allEmployees @include(if: $c)
    }
};

如果我不包含所有这些子片段,但所有这些子片段的数据都相同,则中继失败,必须在需要登录用户的所有子组件上声明视图片段似乎很愚蠢。

如何在我的应用程序顶部请求这条数据并将其提供给子组件,而不必包含所有这些片段。

这开始感觉像是反向道具钻探,我必须在我的应用程序的下端声明一个片段并将其传递到链上。

与 allEmployees 相同。这是我应该只获取一次并通过上下文传递或访问的相同数据,但我必须传递所有这些愚蠢的片段或中继抱怨。

4

1 回答 1

1

这是 Relay 的核心模式,尽管冗长,但实际上是非常鼓励的。

在 Relay 中,鼓励子组件以片段的形式自行指定其数据需求。

最终,你最终会积累很多碎片,这些碎片会散布在你的应用程序的其他地方,所以值得指出一些关键的 Relay 特性来说明为什么这样做是好的:

  1. 如果您声明多个请求相同字段的片段彼此相邻,中继将不会向您的 API 发送重复请求。相反,它们都将在一次往返中获取一次。您不必担心引入过度获取/重复查询问题,因为它们在 Relay 中不存在。

  2. Relay 通过 Relay Compiler 引入了一个编译步骤,它可以智能地分析您的 GraphQL 模式和graphql您在代码中定义的任何模板标签。这会生成artifacts,帮助管理获取数据和自动更新 Relay 存储,因此您不必这样做。通过声明大量片段,您可以有效地告诉编译器和存储组件的数据需求,即使它们相同/相似。这里的复制使 Relay 变得很棒。

  3. 位于树根的 QueryRenderer 祖先将处理实际的获取,并且您在树中较低的子组件上定义的片段指示中继编译器和存储在获取数据后将数据发送到何处。这来自#2。

所以,简而言之,要充分利用 Relay,用分片声明你的组件的数据需求,让 Relay 做繁重的工作,不用担心重复和缺乏可重用性。这对你有利。

于 2020-11-27T22:49:21.257 回答