2017-10-12 2 views
0

Ich habe eine Komponente namens PartyDetails, die Daten benötigt, die von einem Ajax-Aufruf abgerufen werden. Ich möchte eine Komponente Loading zeigen, während die Ajax-Anfrage läuft.Gibt es einen besseren Weg, um diesen reduktiven Anwendungsfall zu bearbeiten?

Das Problem ist, dass, um festzustellen, ob die Daten geladen sind oder nicht, ich brauche Zugriff auf den Speicher. Dies ist, wie Aussehen zu verbessern meine wie:

const enhance = compose(
    propSetter, 
    lifecycleEnhancer, 
    loading, 
) 

export default enhance(PartyDetails) 

wo propSetter ist:

const propSetter = connect((state) => { 
    const { party } = state 
    const { dataLoaded } = party 
    // for some reason state does not contain match, and I'm resorting to routing 
    const { routing: {location: { pathname }}} = state 
    const involvedPartyId = pathname.substring(pathname.lastIndexOf('/') + 1) 
    return { dataLoaded, involvedPartyId } 
}, {loadParty}) 

und lifecycleEnhancer ist:

const lifecycleEnhancer = lifecycle({ 
    componentDidMount() { 
     this.props.loadParty(this.props.involvedPartyId) 
    } 
}) 

und loading wird (in diesem Fall bemerken, dataLoaded kommt aus die vorherige connect, die in propSetter gemacht wurde):

Also im Grunde, wenn die Daten abgerufen wurden, verwende ich eine zweite Verbindung, um die relevanten Requisiten für zu erhalten.

Ich habe vor ein paar Tagen angefangen, recompose zu lernen, und ich konnte kein Beispiel finden, das zu meinem Anwendungsfall passte. Das obige ist, was ich nach dem Lesen der Dokumente und einigen Beispielen in anderen Artikeln gefunden habe.

Ist das, was ich mache, ein guter Weg, dies zu behandeln? Könnte dies besser gemacht werden, vielleicht ohne 2 connect Anrufe?

Antwort

0

Sie könnten alle Ihre Logik für die Zuordnung von Staat und Versand an Requisiten in einer Verbindung schreiben:

export default compose(
    connect(
    state => { 
     const { party } = state; 
     const { dataLoaded } = party; 
     const { routing: { location: { pathname } } } = state; 
     const involvedPartyId = pathname.substring(pathname.lastIndexOf("/") + 1); 

     // also put here your `mapStateToProps` code 

     return { dataLoaded, involvedPartyId }; 
    }, 
    { 
     loadParty 
     // the same here, append `mapDispatchToProps` logic 
    } 
), 
    lifecycle({ 
    componentDidMount() { 
     this.props.loadParty(this.props.involvedPartyId); 
    } 
    }), 
    branch(
    ({ dataLoaded }) => dataLoaded, 
    renderComponent(PartyDetails), 
    renderComponent(Loading) 
) 
    // as `branch` is returning HOC, we need to provide empty component to it in 
    // order to render whole component 
)(createSink()); 
+0

Der Grund, warum ich nicht alles in einem connect habe, ist, dass die Daten nicht in dem Zustand vorhanden ist, wenn die erste Verbindung wird aufgerufen. Gibt es etwas, das ich in deinem Beispiel vermisse? – Geo

+0

@Geo ist eigentlich kein Problem. In meinem Beispiel ist die Render-Datenvariable zunächst undefiniert (da sie zu diesem Zeitpunkt nicht existiert) und wir werden die Lade-Komponente rendern, wenn diese Daten nicht benötigt werden. Wenn beim zweiten Rendervorgang Daten vom Server abgerufen werden, rendern wir 'PartyDetails' und leiten die abgeleiteten Daten weiter – 1ven

Verwandte Themen