2016-05-18 6 views
0

Ich mache eine App, die zu einem bestimmten Zeitpunkt einen Feed von Informationen mit Titel, Beschreibung und Benutzerinformationen abrufen soll. Ich mache das in Reaktion nativ, das sind auch zwei separate Feeds innerhalb der gleichen Ansicht, die zwischen zwei Tabs wechseln können, also dachte ich, dass meine aktuelle Architektur anschließend optimal wäre.Probleme mit Komponenten-Lebenszyklen/kann nicht undefined umgehen

Das Problem bei der Hand:

Von Methods.js:

exports.getFriendFeed = function(TOKEN) { 
    return new Promise((resolve, reject) => { 
     fetch(baseUrl + 'feed' , { 
     method: 'GET', 
     headers: { 
     'Accept': 'application/json', 
     'Content-Type': 'application/json', 
     'Token' : TOKEN, 
     }, 
    }) 
    .then((response) => response.text()) 
    .then((responseText) => { 

     resolve(responseText); 
    }) 
    .catch((error) => { 
     reject(error); 
    }); 
    }); 
}; 

Ich schreibe die Anfrage holen und es zu meinem home.js Bildschirm senden. Und bearbeite es wie folgt:

var Home = React.createClass({ 
. 
. 
. 
    changeComponent: function(component) { 
    Method.getFriendFeed(this.state.tokenSupreme) 
    .then((res) => this.setState({ 
     friendFeed: JSON.parse(res).friendPosts, 
     loaded: true, 
    })) 
    .catch((error) => console.log(error)) 
    .done();  
    this.setState({ 
     componentSelected: component, 
    }) 
    }, 

Das bedeutet, dass wenn ich in eine bestimmte feed-view drücken der Inhalt speziell für diese Ansicht geladen wird.

die Komponente Rendering und die Requisiten der Informations Feed vorbei und ob es geladen ist:

renderComponent: function(component) { 
     if(component === 'One') { 
     return <ComponentOne 
     friendData={ 
      this.state.friendFeed 
     } 
     loaded={ 
      this.state.loaded 
     } /> 
     } else if(component === 'Two') { 
     return <ComponentTwo /> 
     } 
    }, 

Aber jetzt kommt das eigentliche Problem. Befolgen Sie die Dokumentation von React Native. Ich habe console.log 'ed die RowData, die "Laden" und dann gibt es die JSON-Format Daten, die ich will. Dies bedeutet, dass es zuerst die changeComponent-Funktion erfolgreich durchläuft und "loading" wird, und fälschlicherweise this.state.loaded zu true wird, dies bedeutet jedoch, dass es einen Zeitpunkt während dieser Ausführung gibt, an dem ich keine spezifischen Schlüssel oder Namen aufrufen kann Mein JSon ist aufgrund der Tatsache, dass es nur "irgendwie" geladen hat, einfach unbestimmt zurückkehrt und die App sofort rot schirmt.

var ComponentOne = React.createClass({ 
    getInitialState: function() { 
    var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 
    return { 
     dataSource: ds.cloneWithRows(this.props.friendData), 
    }; 
    }, 

    render: function() { 
    if (!this.props.loaded) { 
     return this.renderLoadingView(); 
    } else { 
    return (
     <ListView 
      dataSource={this.state.dataSource} 
      renderRow={this.renderRow} 
      style={styles.card} /> 
    ) 
    } 
    }, 
    renderLoadingView: function() { 
    return ( 
     <View style={{alignItems: 'center', alignSelf: 'center', marginTop: 150, justifyContent: 'center'}} > 
     <Text style={{fontSize: 30, fontWeight: '400', color: '#666'}}> Loading ... </Text> 
     </View> 
    ); 
    }, 

    renderRow: function(rowData) { 
    return (
     <CardView 
      name={rowData.name} 
      fullname='xyz' 
      distance='xyz' 
      title={rowData.title} 
      message={rowData.description} 
      score='xyz' 
      stars='xyz' 
      starcolors={colors.General.black} 
      vouched="Example" /> 
    ) 
    } 
}) 

Warum gibt es mir diese ?? Es wird nie wirklich ausgelöst, wenn ich den Fetcher in ein componentDidMount setze und wenn ich es in ein Rendering lege, feuert es ad infinitum.

Wie kann ich dieses Ausführungs-/Lebenszyklusproblem effizienter steuern? Ich habe auch versucht, es zu einem IF-Statement zu machen, das if (this.props.friendFeed.friend.name !== undefined) sagt, aber glauben Sie es oder nicht, es gibt gerade einen roten Schirm zurück und sagt this.props.friendFeed.friend.name is undefined. Könnte es ein Problem sein, ein Objekt innerhalb eines Schlüssels anzurufen? Kann ich so etwas nennen, ohne dass es vorher definiert wurde?

Antwort

0

Ich sehe zwei mögliche Lösungen. Zunächst zu Ihrer letzten Frage zum Aufruf eines Schlüssels für ein undefiniertes Objekt. Betrachten Sie dieses Objekt ...

{ 
    foo: { 
    bar: 'text' 
    } 
} 

Wenn an irgendeinem Punkt foo ist undefined, können Sie nicht überprüfen, ob ein Unterobjektschlüssel auch undefined ist. Sie müssen das oberste Root-Objekt ermitteln, das beim Laden der Daten nicht definiert werden kann.

So würde diese Aussage fehlschlagen: if (foo.bar !== undefined) wenn foo ist undefined. Allerdings wäre diese Aussage in Ordnung: if (foo.hasOwnProperty('bar')) oder technisch sogar if (foo !== undefined).

Was Ihr Hauptproblem anbelangt, denke ich, dass beim Parsen der Daten etwas Asynchrones passiert. So implementiere ich fetch ...

function checkStatus(response) { 
    if (response.status >= 200 && response.status < 300) { 
    return response.text().then((text) => { 
     if (text == "") return "" 
     return JSON.parse(text) 
    }) 
    return response.json() 
    } 
} 

get(id, query) { 
    let url = this.API_URL() + '/' + id + this._generateQuery(query) 
    return fetch(url, { 
    method: 'get', 
    headers: this._headers() 
    }).then(this._checkStatus) 
    .then((data) => { 
     return data 
    }) 

}

Beachten Sie, wie ich in die Versprechen Seite der Verarbeitung des Körpers in einen Text tippen haben. Ich würde versuchen, so etwas in Ihrem changeComponent zu tun, so dass es setState nicht aufruft (und anschließend das Laden auf true setzt), bis Sie sicher sind, dass die Daten analysiert werden. Da es inline ist, könnte es setState sofort aufrufen und dann für einen kurzen Moment die Komponente mit unvollständigen Daten rendern, während das Parsing beendet wird (da es nur die Variablenreferenzen passiert, keine Werte).