На каком уровне вложенности компоненты должны читать объекты из Stores in Flux?

Я переписываю свое приложение, чтобы использовать Flux, и у меня проблема с получением данных из магазинов. У меня много компонентов, и они много гнездятся. Некоторые из них большие (Article), некоторые маленькие и простые (UserAvatar, UserLink).

Я боролся с тем, где в иерархии компонентов я должен читать данные из магазинов.
Я попробовал два крайних подхода, ни один из которых мне не понравился:

Все компоненты сущности читают свои собственные данные

Каждый компонент, которому нужны данные из Store, получает только идентификатор объекта и самостоятельно извлекает объект.
Например,Article передаетсяarticleId, UserAvatar а такжеUserLink переданыuserId.

Этот подход имеет несколько существенных недостатков (обсуждается в примере кода).

var Article = React.createClass({
  mixins: [createStoreMixin(ArticleStore)],

  propTypes: {
    articleId: PropTypes.number.isRequired
  },

  getStateFromStores() {
    return {
      article: ArticleStore.get(this.props.articleId);
    }
  },

  render() {
    var article = this.state.article,
        userId = article.userId;

    return (
      <div>
        <UserLink userId={userId}>
          <UserAvatar userId={userId} />
        </UserLink>

        <h1>{article.title}</h1>
        <p>{article.text}</p>

        <p>Read more by <UserLink userId={userId} />.</p>
      </div>
    )
  }
});

var UserAvatar = React.createClass({
  mixins: [createStoreMixin(UserStore)],

  propTypes: {
    userId: PropTypes.number.isRequired
  },

  getStateFromStores() {
    return {
      user: UserStore.get(this.props.userId);
    }
  },

  render() {
    var user = this.state.user;

    return (
      <img src={user.thumbnailUrl} />
    )
  }
});

var UserLink = React.createClass({
  mixins: [createStoreMixin(UserStore)],

  propTypes: {
    userId: PropTypes.number.isRequired
  },

  getStateFromStores() {
    return {
      user: UserStore.get(this.props.userId);
    }
  },

  render() {
    var user = this.state.user;

    return (
      <Link to='user' params={{ userId: this.props.userId }}>
        {this.props.children || user.name}
      </Link>
    )
  }
});

Недостатки этого подхода:

Это расстраивает, что 100-е компоненты могут быть подписаны на магазины;Этотрудно отслеживать, как данные обновляются и в каком порядке потому что каждый компонент извлекает свои данные независимо;Даже если вы могли быуже если сущность находится в состоянии, вы вынуждены передать ее идентификатор дочерним элементам, которые получат его снова (или нарушат согласованность).Все данные читаются один раз на верхнем уровне и передаются компонентам

Когда мне надоело отслеживать ошибки, я пытался поставить все данные на верхний уровень. Это, однако, оказалось невозможным, потому что для некоторых объектов у меня есть несколько уровней вложенности.

Например:

A Category содержитUserAvatarлюди, которые вносят вклад в эту категорию;Article может иметь несколькоCategorys.

Поэтому, если бы я хотел получить все данные из магазинов на уровнеArticleМне нужно будет:

Получить статью изArticleStore;Получить все категории статей изCategoryStore;Отдельно получить вкладчиков каждой категории изUserStore;Каким-то образом передать все эти данные в компоненты.

Еще более разочаровывающе, когда бы мне ни понадобилась глубоко вложенная сущность, мне нужно было бы добавлять код на каждый уровень вложенности, чтобы дополнительно передать его.

Подводя итоги

Оба подхода кажутся ошибочными. Как мне решить эту проблему наиболее элегантно?

Мои цели:

У магазинов не должно быть безумного количества подписчиков. Это глупо для каждогоUserLink слушатьUserStore если родительские компоненты уже делают это.

Если родительский компонент извлек некоторый объект из хранилища (например,user), Я не хочу, чтобы какие-либо вложенные компоненты приходилось загружать снова. Я должен быть в состоянии передать это через реквизит.

Мне не нужно извлекать все объекты (включая отношения) на верхнем уровне, потому что это усложнит добавление или удаление отношений. Я не хочу вводить новые реквизиты на всех уровнях вложенности каждый раз, когда вложенная сущность получает новые отношения (например, категория получаетcurator).

Ответы на вопрос(4)

Ваш ответ на вопрос