react-router-relay 是不是与 Relay 模式不一致?

Posted

技术标签:

【中文标题】react-router-relay 是不是与 Relay 模式不一致?【英文标题】:Is react-router-relay inconsistent with the Relay pattern?react-router-relay 是否与 Relay 模式不一致? 【发布时间】:2016-11-19 19:27:21 【问题描述】:

我在一个项目中使用react-router-relay。考虑到每个组件基本上都以一个与根查询同名的片段结束,这个设计对我来说似乎很不合适。每个组件不应该能够在根查询下拥有任意类型的唯一命名片段吗?是否可以使用这个包或者我的想法在这里有缺陷?

编辑:也许我的问题有点含糊。我的问题是,react-router-relay 定义的查询属性基本上有两条规则,它们强制执行在我看来是一种奇怪的设计模式。这两条规则是:

    每个查询只能深入“一级”。 每个查询都必须映射到使用它的组件上具有相同名称的片段。

这给您留下了一个场景,您可以:

    对每个组件使用相同的“查看器”查询,并在每个组件上定义一个互补的“查看器”片段。尽管名称相同,但这些片段都会定义不同的数据要求,这看起来很混乱。 您为不同的组件创建唯一的片段名称,然后根据您要获取的数据类型使用不同的名称重复相同的确切根查询,这看起来非常愚蠢。

【问题讨论】:

【参考方案1】:

好问题。当您处理 Relay 时,您的想法是正确的,因为每个组件都应该有自己的片段,以便查询本身准确地映射到该特定组件所需的数据。片段的命名可以随心所欲,但类型不能随意。它必须是根查询对象(或您将片段附加到的任何字段)下的声明类型。否则片段会抛出一个错误,说您无法在 Query 或字段上查询该类型。

例如:

var componentOneFragment = Relay.QL`
    fragment on User 
        name
    
`;

这里要注意的一点是,您不需要为像fragment userFragment on User ... 这样的片段命名。这将在通过声明$Component.getFragment(componentOneFragment) 从路由器中的中继查询动态引用组件片段时为您提供更大的灵活性。希望这会有所帮助!

编辑:

对每个组件使用相同的“查看器”查询并定义一个 每个组件上的免费“查看器”片段。这些碎片 都会定义不同的数据要求,尽管有相同的 名字,看起来很混乱。

虽然片段的相同名称可能看起来令人困惑,但这是思考问题的最佳方式。每个组件确实有不同的数据需求,所以它们的 Relay 容器自然会有不同的 Fragment,但仍然使用相同的 Fragment 名称。

此片段可能包含在需要用户数据的 Relay 容器之一中:

const WidgetList = Relay.createContainer(/* ... */, 
  initialVariables: 
    color: null,
    size: null,
    limit: null
  ,

  fragments: 
    viewer: () => Relay.QL`
      fragment on User 
        widgets(color: $color, size: $size, first: $limit) 
          edges 
            node 
              name,
            ,
          ,
        ,
      
    `
  
);

虽然这个片段(仍然具有相同的名称)可能包含在另一个需要 Widget 数据的 Relay 容器中:

const ActionsList = Relay.createContainer(/* ... */, 
  initialVariables: 
    input: null
  ,

  fragments: 
    viewer: () => Relay.QL`
      fragment on Widget 
        actions(input: $input) 
          edges 
            node 
              name,
            ,
          ,
        ,
      
    `
  
);

只要 UserWidget 都是 Root Query 对象下的类型,它们都可以在同一个 GraphQL 查询中动态使用(即$Component.getFragment('viewer'))。

【讨论】:

感谢您的回复!我了解查询和片段必须在给定 GraphQL 模式的上下文中有意义。如果您查看编辑并且我提出了我的问题,我认为这可能会澄清一些事情。 我仍然不明白为什么这是思考问题的最佳方式。它似乎与我见过的香草中继示例不符,我觉得它使片段更加模糊。如果您有时间解释,我将不胜感激。 将片段视为 GraphQL 查询的构建块。考虑到这一点,很多时候,当您需要不同的数据子选择时,您将重新编写查询标头。或者,如果您想在查看器中查询其他组件所需的不同类型的数据,您可以这样做而无需重新编写查询标头。从代码组织的角度来看,不仅你的 DOM 被分离成组件,而且你的 GraphQL 查询也会根据每个组件的数据需求被“组件化”,这样你就可以准确地知道哪些数据属于哪个组件。跨度>

以上是关于react-router-relay 是不是与 Relay 模式不一致?的主要内容,如果未能解决你的问题,请参考以下文章

石墨烯 Django 和 react-router-relay

react-router-relay 中的嵌套路由

如何将值传递给 react-router-relay 中的根查询

react-router-relay 的子路由查询错误

使用 react-router-relay 访问要在查询中使用的 url 参数

使用具有不同片段字段的相同中继根查询的多个 react-router-relay 路由