2016-07-02 10 views
1

Ich habe eine Reihe von AJAX-Anforderungen, die aufgerufen werden müssen, bevor die Seite gerendert werden kann. Ich benutze react-router 2.4.1. In einem meinen früheren Projekten, die eine ältere Version von reagieren-Router verwendet, Dies ist, wie ich verwenden, um mit diesem Problem fertig zu werden, dannWie pausiert man die Verzögerung einer Komponente vor dem Zustandsübergang?

Router.run(RouteConfig, function(Handler, state){ 
    var promises = state.routes.filter(function(route) { 
     //Every component that needs initial data for rendering will 
     //define a function fetchData in its statics which will return 
     //a promise that will be resolved once all required AJAX calls    
     //are made. 
     return route.handler.fetchData; 
    }).map(function(route) { 
     return route.handler.fetchData(state.params, state.query); 
    }); 
    if(promises.length > 0) { 
     Promise.all(promises).then(function(response) { 
      data = response; 
      //Rendering will happen only after every call is resolved 
      render(Handler, data); 
     }).catch(function(response, err) { 
      data = response; 
      data.isError = true; 
      data.splice(err.index, 1, err.reason); 
      render(Handler, data); 
     }); 
    } else { 
     render(Handler, data); 
    } 
}); 

function render(Handler, data) { 
    React.render(<Handler data={data}/>, document.body); 
} 

In der neuen Version gibt es keine Router.run ich sehe. Wie kann ich dasselbe in 2.4.1 erreichen?

Antwort

2

Sie können versuchen, die vom Router bereitgestellten onEnter-Hooks zu verwenden. Ich werde mein aktuelles Setup mit dem React Router zeigen. Denken Sie daran, dass ich die Abhängigkeiten auf den Routen und nicht auf Komponenten deklariere, aber Sie können dieses Verhalten ändern, um Ihre Bedürfnisse zu erfüllen.

Nehmen Sie diese Liste von Routen, wie zB:

<Route path="/" onEnter={fetchDependencies} component={AppContainer}> 
    <IndexRedirect to="/home" /> 
    <Route path="/home" component={StaticContainer} require={loadStaticPage} /> 
    <Route path="/contact" component={StaticContainer} require={loadStaticPage} /> 
</Route> 

ich meine eigenen Handler an die Spitze Router hinzufügen jede Abhängigkeit zu holen, für die Sie gerade onEnter eine Funktion für die Eigenschaft festlegen müssen. Ich habe auch eine benutzerdefinierte Eigenschaft auf den Routen, die einige Abhängigkeiten benötigen, benannte ich diese Prop require und es kann einfach eine Funktion sein, die ein Versprechen zurückgibt. In Ihrem Fall verwenden Sie die Komponente dafür.

Diese onEnter nimmt eine Funktion mit der folgenden Signatur:

onEnter(nextState, replace, callback?)

Der Rückruf ist optional und vorgesehen, wenn der Router die Komponente nicht machen, bis der Rückruf ohne Fehler aufgerufen wird. Das ist das Verhalten, das du vorgibst.

Dies ist, wie ich die Abhängigkeiten holen, können Sie diesen Code an Ihre Bedürfnisse

function fetchDependencies(toRoute, redirect, done) { 
    const { routes, params, location } = toRoute; 
    const payload = Object.assign({}, location, { params }); 
    const promises = routes 
    .map(({ require }) => require) 
    .filter(f => typeof f === 'function') 
    .map(f => f(payload)); 

    return Promise.all(promises).then(() => done() , done); 
} 

In Ihrem Fall passen Sie die Komponente anstelle der Eigenschaft erfordern können. Ändern Sie einfach die Kartenfunktion, um stattdessen die Karte zurückzugeben. Also diese Linie

.map(({ require }) => require)

möchte etwas geändert werden

.map(({ component }) => component.fetchData)

Dies ist nur eine Idee, der Code, den ich eingefügt habe, ist nur eine vereinfachte Version des Setup, dass ich benutzen. Mein derzeitiges Setup ist an Redux gebunden und ich habe versucht, jeden Hinweis auf redux in diesen Beispielen zu entfernen, weshalb es keinen Sinn ergibt. Ich benutze auch isomorphes Rendering, daher sind meine Handler ein bisschen komplexer und ich brauche den Callback auf dem Client nicht, da der Redux das Rendern übernimmt, sobald die Abhängigkeit abgerufen wird.

Aber Sie bekommen die Grundidee. Sie müssen mit OnEnter Hook spielen. Dort können Sie alle Abhängigkeiten abrufen und die Callback-Funktion aufrufen, sobald Sie fertig sind. Es ist genau wie dein altes Setup, aber auf eine etwas andere Art und Weise organisiert.

+0

Vielen Dank @andre .. –