2015-09-26 17 views
18

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

レットダイジェストを例に挙げてみましょう:各コメントは、コメントなどを持つことができる子コメントを持つことができます。 簡略化の理由から、コメントは{id、pageId、value、children}タイプのレコードであり、pageIdはredditページ。

どのように減速機をモデル化すればよいでしょうか?私は、減速機をpageIdを使ってページごとにフィルタリングできるコメントのマップIDにすることを考えていました。

たとえば、ネストされたものにコメントを追加する場合は、マップのルートにレコードを作成し、そのIDを親の子プロパティに追加する必要があります。すべてのコメントを表示するにはそれらのすべてを取得し、上部にあるものをフィルタリングする必要があります(これは、たとえばorderedListとしてページリデューサ内に保持されます)。その後、反復処理を行い、子供が出会ったときにコメントオブジェクトから取得します。再帰。

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

+0

私はnormalizrを試すことができると思います:https://github.com/gaearon/normalizr自分で使っていないので、あなたの場合に役立つかどうかはわかりません。 – Simon

+0

私はnormalizrについて知っています、コンポーネントでそれをどう扱うかについて「受け入れられた」解決策があるかどうかさらに疑問に思います。 コメントごとにconnect()をしない限り、各変更時にnormalizrの反対を行う必要があります。接続しても混乱のように見えます。 –

答えて

32

これを公式ソリューションは、このようなあなたの状態を維持するためにnormalizrを使用することです:

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

あなたは、各再帰的にそれが興味を持ってchildrenを照会することができますので、あなたがconnect()Commentコンポーネントを必要とするだろうということですねin Reduxストアから:

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; 

これは良い妥協案だと考えています。 commentを小道具として渡しますが、コンポーネントはchildrenCommentsを店舗から取得します。

+0

実際にSchemaでどうやってそれを行うのですか?どうぞ教えてください – alexrogins

+0

この例では、normalizrを使用しています:https://github.com/reactjs/redux/tree/master/examples/real-world。また、normalizrには、うまくいけばそれを使用する方法を示すべきテストがあります。 –

+0

あなたのデータがAPIから来ていない場合はどうなりますか?私はnormalizrのように私のデータをモデル化するべきですか? – Dave

1

あなたの店舗(リデューサー)の構造は、希望のビューモデル(あなたがコンポーネントに小道具として渡すもの)と異なる場合があります。すべてのコメントを配列に保持し、高レベルの 'スマート'コンポーネントのmapStateToPropsのリンクを使ってツリーにマップできます。あなたは減速機で簡単な状態管理を行い、コンポーネントが動作するのに便利なビューモデルを得るでしょう。