2016-10-13 4 views
1

Ich habe Apollo mit React ausprobiert und stehe derzeit vor einem Problem damit.React-Apollo inkohärente Daten

Ich habe Grunddaten, bei denen ein Produkt zu viele Kategorien gehört

query getProduct{ 
    product(id: 1){ 
     id 
     name 
     categories{id,name} 
    } 
} 

Wie erwartet dies so etwas wie dieses gibt

{ 
    "data": { 
    "p": { 
     "id": 1, 
     "name": "Samsung Galaxy S7", 
     "categories": [ 
     { 
      "name": "Phone" 
     }, 
     { 
      "name": "Samsung" 
     } 
     ] 
    } 
    } 
} 

Hier ist meine Komponente

class TileProductComponent extends Component{ 

    constructor(...args){ 
     super(...args) 
    } 

    render(){ 
     if(this.props.data.loading) 
      return <div>Loading...</div> 

     var product = this.props.data.p 

     console.log(this.props.data) 

     return (
      <div> {product.name} </div> 
     ) 
    } 
} 

var TileProduct = graphql(
    gql` 
     query TestQuery($id: Int!){ 
      product(id: $id){ 
       id 
       name 
       categories{id,name} 
      } 
     } 
    `, 
    { 
     options : { 
      variables : {id:1} 
     } 
    } 
)(TileProductComponent) 

reagieren Aber einmal Es wird in der react-Komponente übergeben, die ich gefunden habe (aus der console.log (this.props.d) ata))

"product": { 
     "id": 1, 
     "name": "Phone", 
     "categories": [ 
     { 
      "name": "Phone" 
     }, 
     { 
      "name": "Samsung" 
     } 
     ] 
    } 

Der Produktname übernimmt aus irgendeinem Grund den Namen der ersten Kategorie? Ich schätze, die ID wird auch. Eine Korrektur wäre, den Namen der Felder in den Schemas zu ändern, aber das sollte meiner Meinung nach nicht wirklich funktionieren.

Ist das ein bekanntes Problem oder bin ich der Einzige, der das erlebt? Jede vorgeschlagene Lösung?

+0

Haben Sie eine 'dataIdFromObject' definiert? Es klingt, als ob Ihre Produkte und Kategorien überlappende IDs haben, die Apollo glauben machen, dass sie das gleiche Objekt sind. Können Sie Ihren Apollo-Client-Initialisierungscode einfügen? – stubailo

+0

var netfworkInterface = createNetworkInterface ('http: // localhost: 3030/graphql') \t \t this.client = new ApolloClient ({ \t \t \t netfworkInterface, \t \t \t dataIdFromObject: r => r.id \t \t }) – zbenhadi

+0

Also ich denke, ich muss ein anderes Ergebnis für verschiedene "Sammlungen" zurückgeben, zum Beispiel könnte ich "Produkt." + R.id für die Produkte und so weiter tun, aber woher weiß ich, aus welcher Sammlung es kam, Da ich nur das Dokument selbst habe – zbenhadi

Antwort

0

Das Problem ist mit Ihrer dataIdFromObject Funktion. Diese Funktion muss einen eindeutigen Wert für verschiedene Objekte zurückgeben, die vom Server kommen. Ein einfacher Weg, dies zu tun, ist die Verwendung des Feldes __typename, das in GraphQL mit Ihrem ID-Feld integriert ist. Hier ist ein Code-Schnipsel:

const client = new ApolloClient({ 
    queryTransformer: addTypename, 
    dataIdFromObject: (result) => { 
    if (result.id && result.__typename) { 
     return result.__typename + result.id; 
    } 
    return null; 
    } 
}); 

es im Rahmen einer App verwendet, um zu sehen, die das GitHunt Frontend Beispiel, die SQL inkrementelle IDs verwendet: https://github.com/apollostack/GitHunt-React/blob/380bedaef97f2a0932c1ab33bd964812d4a8a65e/ui/client.js#L42-L48

+0

Vielen Dank für Ihre Hilfe! – zbenhadi