React / Apollo共享查询状态

时间:2017-07-15 12:03:57

标签: javascript reactjs graphql apollo

我有一个非常简单的应用程序,包含列表视图和详细视图。列表视图包含一个graphql查询,该查询映射到包含项目数组的data道具。选择一个项目会实例化一个详细视图,其中该项目的ID用于为该项目组成另一个graphql查询。

const ListView = graphql(ALL_ITEMS, ...)(ListViewComponent);

<ListView data={ [....] }>
  <Detail>
      <Next /> <Prev /> {/* <-- need info from ListView.data */}          
  </Detail>
  { this.props.data.map(....) }
</ListView>

我遇到的麻烦是将上一个/下一个导航添加到该详情视图中。详细信息组件不知道data道具中包含ListView组件中所有项目的内容。在典型的redux应用程序中,我将项目存储为全局应用程序状态,并将它们注入组件中将是微不足道的,但Apollo似乎不会那样工作。它的状态树不是很耗材(例如使用connect())。

我为此看到了一些可能的解决方案,但它们似乎都不是很好:

  • 使用查找currentOffset + 1currentOffset -1的graphql查询包装prev / next导航组件。这绝对是最好的&#34; apollo&#34;解决方案,但问题是该组件不知道currentOffset,因为它没有data道具。此外,我必须确保列表视图查询中的任何其他变量(例如过滤器,排序)都已通过,并且这些变量也位于隐藏的apollo状态树中。
  • 收听我的reducer中的APOLLO_QUERY_RESULT操作,并使用我的其他组件所需的所有信息维护查询结果的第二个副本。
  • 使用context与儿童分享data道具。
  • 明确地将data道具传递给儿童。

似乎是一种常见的情景。什么是正确的方法?

1 个答案:

答案 0 :(得分:2)

将数据作为道具传递可能是最简单的解决方案。

您可能要考虑的另一个选项是将您想要访问相同查询数据的任何组件包装到另一个ALL_ITEMS HOC中。如果您使用用于ListView的HOC(data)的相同查询,则可以像在ListView中一样使用孩子中的{{1}}道具。这种方法的巧妙之处在于 - 只要您use the default fetchPolicy - 您的子组件不会触发针对您的服务器的第二次查询;它只会利用缓存中已有的内容。