23

エンティティが同じタイプの子を持つことができるレデューサーを実装する方法について、私は少し考えています。

例として reddit コメントを見てみましょう: 各コメントには、コメント自体などを持つことができる子コメントを含めることができます。簡単にするために、コメントはタイプ のレコードであり{id, pageId, value, children}pageIdreddit ページです。

その周りのレデューサーをどのようにモデル化しますか? レデューサーをマップにすることを考えていました->を使用してページごとにフィルターできるコメントのID pageId

問題は、たとえば、ネストされたコメントにコメントを追加する場合です。マップのルートにレコードを作成し、その id を親子プロパティに追加する必要があります。すべてのコメントを取得するために必要なすべてのコメントを表示するには、一番上にあるもの (たとえば、orderedList としてページ レデューサーに保持されるもの) をフィルター処理してから、コメント オブジェクトから取得するときにそれらを反復処理します。再帰を使用して子に遭遇します。

それよりも良いアプローチはありますか、それとも欠陥がありますか?

4

2 に答える 2

40

これに対する公式の解決策は、normalizrを使用して状態を次のように保つことです。

{
  comments: {
    1: {
      id: 1,
      children: [2, 3]
    },
    2: {
      id: 2,
      children: []
    },
    3: {
      id: 3,
      children: [42]
    },
    ...
  }
}

Reduxストアから興味のあるものを再帰的にクエリできるようにconnect()、コンポーネントが必要なのは間違いありません。Commentchildren

class Comment extends Component {
  static propTypes = {
    comment: PropTypes.object.isRequired,
    childComments: PropTypes.arrayOf(PropTypes.object.isRequired).isRequired
  },

  render() {
    return (
      <div>
        {this.props.comment.text}
        {this.props.childComments.map(child => <Comment key={child.id} comment={child} />)}
      </div> 
    );
  }
}

function mapStateToProps(state, ownProps) {
  return {
    childComments: ownProps.comment.children.map(id => state.comments[id])
  };
}

Comment = connect(mapStateToProps)(Comment);
export default Comment;

これは良い妥協点だと思います。commentpropとして渡しますが、コンポーネントchildrenCommentsはストアから取得します。

于 2015-10-03T13:41:35.860 に答える