【问题标题】:How to deal with relations in Flux?如何处理 Flux 中的关系?
【发布时间】:2015-06-17 20:41:03
【问题描述】:

想象一下Quora

[
  {
    type: "question",
    answers: [
      {
        type: "answer",
        upvotes: [
          {
            type: "upvote"
          }
          /* more upvotes */
        ],
        comments [
          {
            type: "comment"
          }
          /* more comments */
        ]
      }
      /* more answers */
    ]
  }
  /* more questions */
]

我肯定会有QuestionsStore 之类的东西。但是对于所有子实体,我不确定如何处理它们。来自Backbone,我认为每个答案都应该有UpvotesStoreCommentsStore,组件将从这些商店获取数据并订阅它们的更新。据我了解 Flux,“子”/关系存储有点不常见。

当每个组件都订阅来自 QuestionsStore 的更新时,会导致类似:

/* in CommentsComponent */
onUpdate: function() {
  this.setState({
    comments: QuestionsStore.getComments({questionId: 1, answerId: 1});
  });
}

或更极端:

/* in CommentComponent */
onUpdate: function() {
  this.setState(QuestionsStore.getComment({questionId: 1, answerId: 1, commentId: 1}));
}

由于关系数据存在于树结构中,因此每个组件都需要知道所有“父”ID,以便能够从QuestionsStore 查询它们的数据。我觉得这有点奇怪。

那么处理关系(一对多)数据结构的最佳 Flux 模式是什么?

【问题讨论】:

  • 您可以让您的 API 返回您需要的任何数据,也可以采用基于承诺的结构,其中每个承诺都会解析它需要的数据。
  • 相关和重叠:thisthis
  • 还有这个,同一个问题:stackoverflow.com/questions/31641466/…

标签: javascript reactjs reactjs-flux flux


【解决方案1】:

我看到的两个主要选项是保留嵌套结构,或者将其解析为平面结构,其中每个对象都根据它们的关系包含对其他对象的引用。我认为最好的方法取决于需要如何访问数据。

嵌套结构

如果它始终反映您的视图层次结构,那么保持嵌套结构会使事情变得相对容易。例如,考虑:

// render a <Question/>
render: function() {
  var question = this.props.data,
      answers = question.answers.map(function(answer, i) {
        return <Answer key={i} data={answer}/>
      });

  return (
    <div className="question">
      {answers}
    </div>
  );
}

// render an <Answer/>
render: function() {
  var answer = this.props.data,
      comments = answer.comments.map(function(comment, i) {
        return <Comment key={i} data={comment}/>
      });

  return (
    <div className="answer">
      ...
      {comments}
    </div>
  );
}

// and so on

让一个顶级组件从 store 中获取数据并通过 props 传递它比让每个组件跟踪索引以在 Store 中查找嵌套数据要容易得多。

这种方法的潜在缺点是嵌套数据更难从其上下文之外访问。例如,如果您想跟踪给定用户的所有评论,您的用户数据仍然需要借助索引来跟踪哪些问题、每个问题的哪些答案索引以及每个答案的哪些评论索引指向正确的评论。在这种情况下,您可能会受益于扁平数据结构。

扁平结构

平面结构需要更多的工作来设置,但优点是每个对象都可以立即访问。假设您的数据以嵌套对象的形式出现,则需要通过遍历树来查找所有节点,给每个节点一个唯一的键,将其子树替换为对适当键的引用,然后将所有结果存储在合适的商店。但正如 Dan Abramov 指出的那样,有人已经提供了 module 来促进这一点。

现在您的问题可以引用答案,每个答案都可以引用评论,从而可以轻松地重新创建原始嵌套结构;但您的用户也可以参考评论,而无需跟踪它们与答案或问题的关系。

这基本上就是 Git 内部的工作方式;它对于包含大量冗余的数据树尤其有效(例如,包含未更改文件的多个提交都可以指向同一个对象)。

【讨论】:

  • 问题更多是关于商店,而不是关于组件。
  • “但正如 Dan Abramov 指出的那样,有人已经提供了一个模块来促进这一点。”那个人实际上是丹 :)
  • normalizr 可以帮助解决这个问题,它允许您提供架构,以便您可以保持数据平坦。见github.com/gaearon/normalizr
猜你喜欢
  • 2015-04-23
  • 2015-10-16
  • 2015-06-16
  • 2018-07-09
  • 2015-04-15
  • 2017-03-10
  • 2015-04-12
  • 2011-11-29
相关资源
最近更新 更多