如何从一组中继容器中组合片段?

Posted

技术标签:

【中文标题】如何从一组中继容器中组合片段?【英文标题】:How to compose fragments from an array of relay containers? 【发布时间】:2016-06-07 17:21:19 【问题描述】:

我正在将即时通讯功能构建到我的项目中。该项目使用 React 和 Relay。即时通讯功能类似于 Facebook 聊天,您可以在其中查看要与之交谈的人员列表,然后单击某人将打开一个聊天窗口以进行该一对一讨论。

在我的实现中,您可以与之聊天的用户列表与打开的聊天窗口列表是分开的。因此,用户列表对于这个问题实际上并不重要。

关于打开聊天窗口的渲染,我的方法是创建一个父 React 组件/中继容器。该父组件将跟踪用户打开了哪些聊天窗口,并将构建聊天窗口 React 组件数组并最终渲染它们。这个打开的聊天窗口列表是父 React 组件中的所有本地状态。

单个聊天窗口 React Component / Relay Container 有一个从参数化字段查询的片段,其中参数是与聊天窗口讨论的用户的 id。所以,如果这个聊天窗口是用来和 Bob 讨论的,它就是 Bob 的 id。

考虑到这一点,下面是一个父组件实现示例......

class FloatingDiscussionPane extends React.Component 
  render() 
    return (
      <ul>
        this.renderDiscussions()
      </ul>
    );
  

  renderDiscussions() 
    const teamIds = this.props;
    return teamIds.map(teamId => 
      return (
        <FloatingDiscussionPaneDiscussion
          teamId=teamId />
      );
    );
  
;

export default Relay.createContainer(FloatingDiscussionPane, 
  fragments: 
    session: () => Relay.QL`
      fragment on Session 
        $/* how to get fragments from the array of discussion windows */
      
    `
  
);

这里是聊天窗口的一个示例实现......

class FloatingDiscussionPaneDiscussion extends React.Component 
  render() 
    ...
  
;

export default Relay.createContainer(FloatingDiscussionPaneDiscussion, 
  fragments: 
    session: () => Relay.QL`
      fragment on Session 
        messages: myDiscussionMessages(team: $teamId) 
          ...
        
      
    `
  
);

如您所见,FloatingDiscussionPaneDiscussion 容器有一个片段需要包含在父容器中,FloatingDiscussionPane。父组件FloatingDiscussionPane 将有一个FloatingDiscussionPaneDiscussion 数组,所有这些都需要在父片段中包含自己的片段。

我怎样才能做到这一点?

【问题讨论】:

【参考方案1】:

我暂时假设您的架构是这样的:团队有消息(复数字段,由 GraphQLList 支持)并且会话有团队​​。

窗格组件可以加载所有团队及其嵌套消息。

class FloatingDiscussionPane extends React.Component 
  render() 
    return (
      <ul>
        this.renderDiscussions()
      </ul>
    );
  

  renderDiscussions() 
    const session: teams = this.props;
    return teams.map((id, messages) => 
      return (
        <li key=id>
          <FloatingDiscussionPaneDiscussion messages=messages />
        </li>
      );
    );
  
;

export default Relay.createContainer(FloatingDiscussionPane, 
  fragments: 
    session: () => Relay.QL`
      fragment on Session 
        teams 
          id
          $FloatingDiscussionPaneDiscussion.getFragment('team')
        
      
    `,
  ,
);

每个窗格都可以使用这些消息并显示它们:

class FloatingDiscussionPaneDiscussion extends React.Component 
  render() 
    const team: messages = this.props;
    return (
      <ul>
        messages.map((id, text, sender: name: senderName) => 
          <li key=id>senderName: text</li>
        )
      </ul>
    );
  
;

export default Relay.createContainer(FloatingDiscussionPaneDiscussion, 
  fragments: 
    team: () => Relay.QL`
      fragment on Team 
        messages 
          id
          recipient  name 
          sender  name 
          text
        
      
    `,
  ,
);

【讨论】:

上面的组件层次结构有点粗。您可能希望将其拆分为一个应用程序、一个团队、一个讨论和一个消息组件,每个组件都拥有自己的片段树的一小部分。

以上是关于如何从一组中继容器中组合片段?的主要内容,如果未能解决你的问题,请参考以下文章

中继片段变量

中继现代碎片容器,道具不自动可用

没有数据的中继容器

无法创建中继容器; graphql.js 文件似乎有 webpack 工件?

中继fetchQuery:如何在没有片段结构的情况下获取查询结果

中继片段传播不起作用