Как составить фрагменты из массива релейных контейнеров?

Я встраиваю функцию обмена мгновенными сообщениями в свой проект. В проекте используются React и Relay. Функция обмена мгновенными сообщениями похожа на чат Facebook, где вы можете увидеть список людей, с которыми можно поговорить, и щелкнув по человеку, вы откроете окно чата для этого обсуждения один на один.

В моей реализации список пользователей, с которыми вы можете общаться, отделен от списка открытых окон чата. Таким образом, список пользователей на самом деле не важен для этого вопроса.

Что касается рендеринга открытых окон чата, мой подход к этому заключался в создании родительского компонента React / Relay Container. Этот родительский компонент будет отслеживать, какие окна чата открывал пользователь, и будет строить массив React-компонентов окна чата и, наконец, отображать их. Весь этот список открытых окон чата является локальным состоянием в родительском компоненте React.

Отдельное окно чата React Component/Relay Container имеет фрагмент, который запрашивает из параметризованного поля, где параметром является идентификатор пользователя, с которым ведется обсуждение в окне чата. Итак, если это окно чата предназначено для обсуждения с Бобом, это будет идентификатор Боба.

Имея это в виду, вот пример реализации родительского компонента...

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, и все они должны иметь свои собственные фрагменты, включенные в родительский фрагмент.

Как я могу этого добиться?


person Ryan    schedule 25.02.2016    source источник


Ответы (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
        }
      }
    `,
  },
});
person steveluscher    schedule 09.03.2016
comment
Приведенная выше иерархия компонентов немного грубовата. Скорее всего, вы захотите разбить его, чтобы у вас было приложение, команда, обсуждение и компонент сообщения, каждый из которых владеет своей небольшой частью дерева фрагментов. - person steveluscher; 09.03.2016