2016-11-01 2 views
2

Ich habe den folgenden Code in meiner Render-Methode:Meteor handle.ready() in render() nicht auslösenden rerender der Komponente

render() { 
    return (
     <div> 
       {this.props.spatulaReady.ready() ? <p>{this.props.spatula.name}</p> : <p>loading spatula</p>} 
     </div> 
    ) 
} 

, die nach meinem Verständnis, prüft, ob die subscriptionhandle bereit ist (Daten dort) und zeigt es an. Wenn keine Daten verfügbar sind, sollte eine einfache Ladenachricht angezeigt werden. Wenn ich das erste Mal die Seite lade, auf der dieses Snippet liegt, bleibt es auf dem Ladebereich hängen. Auf einer Seite neu laden die Daten (in der Regel) fein angezeigt.

Wenn ich die SpatulaReady.ready() überprüfen, wenn die Seite zuerst lädt und während die Anzeige auf "Laden Spatel" fest, und die Daten, die da sein sollte, meldet sich der Griff als bereit und die Daten sind da wie es sollte sein. Wenn ich die Seite aktualisiere, wird auch alles gut angezeigt. Das Problem ist, dass diese Art der Überprüfung auf Daten und das Rendering, wenn es angekommen ist, für mich in der Vergangenheit gut funktioniert hat. Liegt es daran, dass die Rendermethode nicht reaktiv ist? Weil handle.ready() reaktiv sein sollte.

Was es noch seltsamer macht, ist, dass es manchmal die Daten beim Laden der Seite scheinbar zufällig anzeigt.

Createcode:

export default createContainer(props => { 
    return { 
     user: Meteor.user(), 
     spatulaReady: Meteor.subscribe('spatula.byId', props.deviceId), 
     spatula: SpatulaCollection.findOne() 
    } 
}, SpatulaConfig) 

Publikationscode:

Meteor.publish('spatula.byId', function(deviceId) { 
    const ERROR_MESSAGE = 'Error while obtaining spatula by id' 

    if (!this.userId) //Check for login 
     throw new Meteor.Error('Subscription denied!') 
    const spatula = SpatulaCollection.findOne({_id: deviceId}) 
    if(!spatula) //No spatula by this id 
     throw new Meteor.Error(403, ERROR_MESSAGE) 
    if(spatula.ownedBy != this.userId) //Spatula does not belong to this user 
     throw new Meteor.Error(403, ERROR_MESSAGE) 

    return SpatulaCollection.find({_id: deviceId}) 

}) 

Ich weiß, dass ich hier ein Stück des Puzzles fehlt, aber ich habe bei der Suche nach es nicht erfolgreich gewesen. Wenn Sie die Lösung für mein spezifisches Problem nicht kennen, wird es auch sehr geschätzt, wenn Sie mich in die richtige Richtung lenken und auf eine andere Art warten, bis die Daten ankommen.

EDIT: Nachdem einigen trial-and-error tun und verschiedene andere Beiträge etwas im Zusammenhang mit meinem Projekt zu lesen, dachte ich, die Lösung aus:

export default createContainer(props => { 
    const sHandle= Meteor.subscribe('spatula.byId', props.deviceId) 
    return { 
     user: Meteor.user(), 
     spatulaReady: sHandle.ready(), 
     spatula: SpatulaCollection.findOne() 
    } 
}, SpatulaConfig) 

Es macht noch keinen Sinn für mich, dass die bereit zu bewegen () Aufruf zum Erstellen von Container behoben alle meine Probleme obwohl.

+0

Versuchen Sie, den Aufruf '.ready()' im Container zu platzieren. Ich glaube, dass es mit der Reaktivität zusammenhängt. – MasterAM

Antwort

1

Wie Sie herausgefunden haben, behebt das Verschieben des .ready() Anrufs auf createContainer das Problem. Dies liegt daran, Meteor Reaktivität funktioniert nur, wenn Sie eine reaktive Datenquelle nennen (eine reaktive Funktion), wie collection.find() oder subscriptionHandle.ready() innerhalb eines reaktiven Zusammenhang, wie Tracker.autorun oder createContainer. Funktionen innerhalb der React-Komponente, einschließlich render, sind nicht reaktive Kontexte aus Meteor-Perspektive.

Beachten Sie, dass React und Meteor Reaktivität zwei verschiedene Dinge sind. Reacts Reaktivität funktioniert einfach so, dass, wenn sich eine Komponente props oder state ändert, die render Funktion erneut ausgeführt wird. Es versteht nichts über reaktive Datenquellen von Meteor. Da createContainer (das heißt wieder von Meteor Reaktivität ausgeführt wird, wenn reaktive Datenquellen darin ändern) einfach Requisiten an die zugrunde liegende Komponente übergibt, wird die Komponente von React erneut gerendert, wenn sich die Requisiten von createContainer ändern.

+0

Danke, diese Erklärung räumt die Verwirrung auf! –

Verwandte Themen