尝试创建更动态/可重用的根级别QueryRenderer

时间:2017-08-09 16:16:42

标签: reactjs relayjs relay relaymodern

我一直致力于实现一个通用<QueryRenderer/>,它从根级别作为单一的事实来源,最终分支成多个片段。我的初始实现静态定义了查询本身内的片段,并将接收组件作为道具,如此......

...
class ComponentRenderer extends React.Component {
  render() {
    const ComponentRendererQuery = graphql`
      query ComponentRendererQuery(
        $globalId: ID 
      ) {
        viewer {
          ...Fragment1_viewer
          ...Fragment2_viewer
          ...Fragment3_viewer
          ...Etc_viewer
        }
      }
    `

    const Component = this.props.component;

    return (
      <QueryRenderer
        environment={environment}
        query={ ComponentRendererQuery }
        variables={{
          globalId: this.props.match.params.id
        }}
        render={({ error, props }) => {
          if (error) {
            return <div>{error.message}</div>
          } else if (props) {
            return <Component {...this.props} viewer={props.viewer} />
          }
...

这个设置对我来说或多或少都很有效,因为我没有<QueryRenderers/>到处都是个人偏好,我觉得这个设置有点清洁。然而,我设法忽略了一个细节 - 我要求传播到根级别查询中的所有片段。我假设由于活动的React组件保留了其余的片段,其他的将被忽略,但事实并非如此。

我认为这种行为是由于Relay如何预先构建您的数据模型,因此所有片段都保留在范围内。所以我的实现必然会破坏我的应用程序,然而它会产生相当多的过度获取并在服务器中为依赖于参数的任何片段创建一些异常(在此示例中,我传递GraphQL全局标识符以生成更详细的在另一页上查看。)

所以我尝试了另一种方法,认为我可能只是预定义了我的查询并将它们传递给我创建的通用<ComponentRenderer/>

const Fragment1Query = graphql`
  query FragmentQuery {
    viewer {
      ...Fragment1_viewer
    }
  }
`;

const Fragment2Query = graphql`                                                                                                                                                                      
  query FragmnetQuery {
    viewer {
      ...Fragment2_viewer
    }
  }
`;

const hasId = this.props.match.params.id;
const Component = hasId ? Component1 : Component2
const Query = hasId ? Fragmen2 : Fragment2

return (
  <ComponentRenderer
    {...this.props}
    component={Component}
    query={Query}
  />
);

我已经在这里重新定位了查询,并将先前被传播到单个根查询中的每个先前片段分配给常量。一旦反对思考我很聪明但没有完全理解Relay在构建时做了什么。

所以问题是Relay会提前构建所有内容,这意味着应用程序的状态保持不变。虽然逻辑上我能够有条件地决定向<QueryRenderer/>呈现哪个片段,但这似乎可以作为Relay的一个优化工作,这取决于定义GraphQL查询的结构和前面的碎片。

有点陷入僵局。我发誓我已经在GitHub上看到了一个漂浮在某处的例子,完成了我正在尝试的但没有保存链接。可能只需要将查询进一步向下移动到其他组件中...实际上可能更合理,因为Relay的预期设计之一是强制组件控制自己的数据需求。

编辑:以下是我今天遇到的一个示例,解决了Relay Classic中的类似问题。不幸的是,这已经发生了很大的变化,这并没有将所有这一切彻底地转化为现代......但它让我更加希望。 Conditional fragments or embedded root-containers when using Relay with React-Native

0 个答案:

没有答案