2017-01-07 4 views
0

私の目標は、同じRelay fragmentからedgesarraysの複数のネストされた兄弟を組み合わせて1つのrenderコールに結合することです。Relayクエリの結果から深くネストされたノードを取得できますか?

バックエンドデータは、Relayコンテナ(react-router-relayも使用)で配信されます。

複数の異なるUsersからTagsを複数表示するコンポーネント階層があります。トップレベルのクエリは次のようになります。

results = [['tagname1', 'tagname2'], [tagname3, tagname4]] 

は現在、私はComponent、独自に各node Typeと階層をレンダリングする:(完全に平坦化形で)このようなものになり

getUserGroup(id: 'abc') { 
    users { 
    edges { // array of arrays objects with nested arrays 
     node { 
     Tags { 
      edges { // array of objects with target items 
      node { 
       tagName // target item 
       id 
      } 
      } 
     } 
     } 
    } 
    } 
} 

すなわち、Tagmenu - >UserTagGroup - >TagItems(コードはこの記事の最後にあります)。

このグループは、Userによってタグのすべて、最終的にはこのようなリストをレンダリング:私が達成したいのですがどのような

User 1: 
    - Tag 1 
    - Tag 2 
User 2: 
    - Tag 3 
    - Tag 4 

はすべてUsers "タグが混在している一緒秒でrenderです階層、すなわち、TagMenuのような階層 - >TagItemsは、レンダリングするために:私はこれまで管理できる

User Tags 
    - Tag 1 
    ... 
    - Tag 4 

唯一の方法は、手動で抽出して、トップleveのからすべてのアレイを組み合わせることですこのような何か(擬似コード)を持つリットルRelayコンテナ結果:

for each array in users.edges: 
    for each array in node.Tags.edges: 
    return node.tagName 

これは2つの理由のために右のようではありません。

  1. それは
  2. render()機能にパックには少しくらいですそれが可能かどうかは明らかではないto protect against null refs with default props in Relay

...明らかに実行可能です。

私の質問は:Relayどうすればいいですか?どのように自然にライブラリがコンポーネントの構成につながるかを考えると、深くネストされた結果をより高いレベルで引き出し、手動でシャッフルすることが最適であるとは想像もしません。ここに私のコンポーネントです:

// TagsMenu component, top level 
class TagsMenu extends Component { 
    render() { 
    return (
     <div> 
     { 
      this.props.userGroup.users.edges.map(u => { 
      return <UserTagGroup user={u.node} /> 
      }) 
     } 
     </div> 
    ) 
    } 
} 

fragment on UserGroup { 
    users(first: 1000) { 
    edges { 
     node { 
     ${UserTagGroup.getFragment('user')} 
     } 
    } 
    } 
} 


// UserTagGroup, second component 
class UserTagGroup extends Component { 
    render() { 
    return (
     <div> 
     <h4>User: {this.props.user.id}</h4> 
     { 
      this.props.user.Tags.edges.map(t => { 
      return <TagMenuItem tag={t.node} /> 
      }) 
     } 
     </div> 
    ) 
    } 
} 
fragment on User { 
    id 
    listingTags(first: 1000) { 
    edges { 
     node { 
     ${TagMenuItem.getFragment('tag')} 
     } 
    } 
    } 
} 


// TagMenuItem, bottom level component. Renders 1 Tag. 
class TagMenuItem extends Component { 
    render() { 
    return (
     <div> 
     {this.props.tag.tagName} 
     </div> 
    ) 
    } 
} 
fragment on Tag { 
    tagName 
    id 
} 

答えて

0

あなたが記述されてきたもの - 「手動でトップレベルのリレーコンテナからすべてのアレイを抽出し、組み合わせた」 - しかし、進むべき道のように見えるん。

render()メソッドでこの機能を使用することに問題がある場合は、状態とメソッドcomponentWillReceiveProps()の組み合わせを使用することをお勧めします。目標は、this.props.usersが本当に変更された場合にのみ、フラット化されたリストを再計算することです。論文のラインに沿って

何か:

class MyRootContainer extends Component { 

    constructor(props) { 
    super(props); 

    this.state = { 
     flattenedList: this.computeFlattenedListFromProps(this.props), 
    }; 
    } 

    componentWillReceiveProps(props) { 
    if (this.props.users !== props.users) { 
     this.setState({ 
     flattenedList: this.computeFlattenedListFromProps(props), 
     }); 
    } 
    } 

    computeFlattenedListFromProps(props) { 
    // Compute and return flattened list 
    } 

    render() { 
    ... 
    } 
} 
関連する問題