2017-01-07 5 views
0

Mein Ziel ist es, mehrere verschachtelte Geschwister arrays von edges aus demselben Relay fragment in einen render Aufruf zu kombinieren.Kann ich tief verschachtelte Knoten aus einem Relay-Abfrageergebnis ziehen?

Backend-Daten werden über Relay Container (auch unter Verwendung react-router-relay) geliefert.

Ich habe eine Komponentenhierarchie, die mehrere Tags von mehreren verschiedenen Users anzeigt. Die Top-Level-Abfrage sieht ungefähr so ​​aus:

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 
      } 
      } 
     } 
     } 
    } 
    } 
} 

, die in so etwas wie dies führt (in vollständig abgeflachten Form):

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

Derzeit mache ich eine Hierarchie mit jedem node Type in seinem eigenen Component , dh Tagmenu ->UserTagGroup ->TagItems (Code ist am Ende dieses Beitrags).

dieser Gruppe alle Tags von User, schließlich eine Liste wie folgt zu machen:

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

Was möchte ich erreichen, ist ein render wo alle Users 'Tags gemischt-in zusammen mit der zweiten Tier, das heißt eine Hierarchie wie TagMenu ->TagItems, zu machen:

User Tags 
    - Tag 1 
    ... 
    - Tag 4 

der einzige Weg, die ich bisher verwalten kann, ist manuell zu extrahieren und alle Anordnungen von oben-leve kombinieren l Relay Behälter Ergebnisse mit so etwas wie diese (Pseudocode):

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

Dies scheint nicht richtig aus 2 Gründen:

  1. Es ist ein bisschen viel in eine render() Funktion zu packen,
  2. Es ist nicht klar, ob es möglich ist to protect against null refs with default props in Relay

... aber es ist offensichtlich machbar.

Meine Frage ist: Was ist die Relay Weg, dies zu tun? Wenn man bedenkt, wie natürlich die Bibliothek zur Zusammensetzung von Komponenten führt, kann ich mir nicht vorstellen, dass tief verschachtelte Ergebnisse auf einem höheren Niveau zu ziehen und manuell zu mischen ist optimal. Hier sind meine Komponenten:

// 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 
} 

Antwort

0

Was Sie schon beschreibt - „manuell extrahieren und alle Arrays aus dem Top-Level-Relay Container kombinieren“ - scheinen wie der Weg zu gehen, wenn.

Wenn das Problem darin liegt, diese Funktion in der render() Methode zu haben, empfehle ich Ihnen, eine Kombination aus Zustand und der Methode componentWillReceiveProps() zu verwenden. Das Ziel, die abgeflachte Liste nur dann neu zu berechnen, wenn sich this.props.users wirklich geändert hat.

Etwas entlang Thesen Linie:

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() { 
    ... 
    } 
} 
Verwandte Themen