【问题标题】: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 数组,所有这些都需要在父片段中包含自己的片段。

我怎样才能做到这一点?

【问题讨论】:

    标签: reactjs graphql relayjs


    【解决方案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
            }
          }
        `,
      },
    });
    

    【讨论】:

    • 上面的组件层次结构有点粗。您可能希望将其拆分为一个应用程序、一个团队、一个讨论和一个消息组件,每个组件都拥有自己的片段树的一小部分。
    猜你喜欢
    • 2016-10-01
    • 2022-07-29
    • 2012-01-04
    • 1970-01-01
    • 2023-01-28
    • 1970-01-01
    • 2019-10-20
    • 2021-02-26
    • 2016-12-14
    相关资源
    最近更新 更多