Sono davvero nuovo su React e non riesco a capire come eseguire il rendering di una schermata di "caricamento in corso ..." quando un percorso viene caricato con getComponent. La chiamata getComponent funziona correttamente e visualizza il componente, ma non c'è alcuna indicazione sull'interfaccia utente che qualcosa stia accadendo tra la richiesta e la risposta. Questo è quello che sto cercando di capire.Come mostrare l'interfaccia utente di caricamento quando si chiama getComponent in react-router?
import Main from './pages/Main.jsx';
import Test from './pages/Test.jsx';
import Home from './pages/Home.jsx';
var Routes = {
path: "/",
component: Main,
indexRoute: {
component: Home
},
childRoutes: [
{
path: "test",
component: Test
},
{
path: "about",
getComponent: function(path, cb) {
require.ensure([], (require) => {
cb(null, require("./pages/about/About.jsx"));
});
}
}
]
};
export default Routes;
Dopo aver cercato di forzare, senza successo, un componente di "carico" per visualizzare usando onEnter o all'interno della funzione getComponent, ho pensato che forse avrei dovuto provare utilizzando Redux per impostare uno stato di caricamento di vero/falso e ottenere il mio componente vista principale per visualizzare una schermata di caricamento:
import React from 'react';
import {connect} from 'react-redux';
import NavBar from '../components/Navigation/NavBar.jsx';
import Footer from '../components/Footer.jsx';
import Loading from './Loading.jsx';
import navItems from '../config/navItems.jsx';
import setLoading from '../actions/Loading.jsx';
var Main = React.createClass({
renderPage: function() {
if (this.props.loading) {
return (
<Loading/>
);
} else {
return this.props.children;
}
},
render: function() {
return (
<div>
<header id="main-header">
<NavBar navigation={navItems}/>
</header>
<section id="main-section">
{this.renderPage()}
</section>
<Footer id="main-footer" />
</div>
);
}
});
function mapStateToProps(state) {
return {
loading: state.loading
}
}
export default connect(mapStateToProps)(Main);
Questo sembra funzionare se ho impostato manualmente lo stato di caricamento con un'azione, che è quello che stavo cercando di fare. Ma (e penso che questa sarà una vera domanda di noob) non riesco a capire come accedere al negozio/dispatcher dal router.
Non sono sicuro se sto usando i termini di ricerca sbagliati o qualsiasi altra cosa, ma sono completamente privo di idee e ogni tutorial di react-router/redux sembra saltare quello che mi sembra debba essere un comune problema.
Qualcuno può indicarmi la direzione giusta (e anche farmi sapere se quello che sto facendo è la migliore pratica?)?
EDIT: Proverò a chiarire un po 'di più. Nel primo blocco di codice, è possibile notare che se faccio clic su un elemento <Link to="/about">
, la funzione getComponent verrà attivata, il che caricherà il componente About.jsx. Il problema che sto avendo è che non riesco a capire come mostrare una sorta di indicatore di caricamento/spinner che apparirà immediatamente dopo aver cliccato sul link e poi averlo sostituito una volta caricato il componente.
ALTRE MODIFICHE: Ho provato a creare un componente wrapper per il caricamento di percorsi asincroni e sembra funzionare, tuttavia si sente davvero hacky e sono sicuro che non è il modo giusto per farlo. Codice Itinerari ora assomiglia a questo:
import Main from './pages/Main.jsx';
import Test from './pages/Test.jsx';
import Home from './pages/Home.jsx';
import AsyncRoute from './pages/AsyncRoute.jsx';
var Routes = {
path: "/",
component: Main,
indexRoute: {
component: Home
},
childRoutes: [
{
path: "test",
component: Test
},
{
path: "about",
component: AsyncRoute("about")
}
]
};
export default Routes;
La pagina AsyncRoute.jsx si presenta così:
import React from 'react';
function getRoute(route, component) {
switch(route) {
// add each route in here
case "about":
require.ensure([], (require) => {
component.Page = require("./about/About.jsx");
component.setState({loading: false});
});
break;
}
}
var AsyncRoute = function(route) {
return React.createClass({
getInitialState: function() {
return {
loading: true
}
},
componentWillMount: function() {
getRoute(route, this);
},
render: function() {
if (this.state.loading) {
return (
<div>Loading...</div>
);
} else {
return (
<this.Page/>
);
}
}
});
};
export default AsyncRoute;
Se qualcuno ha un'idea migliore, per favore fatemelo sapere.
Grazie, è entrambi, ma in questo momento è più un problema con il mio codice e mi sento io potrebbe essere andato nella direzione sbagliata cercando di risolverlo. Modificherò la mia domanda per cercare di chiarire. –
Perché il componente About.jsx richiederebbe così tanto tempo per essere caricato? Stai caricando qualcosa in modo sincrono? Potresti aggiungere uno schizzo di quel componente? – Nicole
About.jsx non impiegherebbe molto tempo a caricarsi dato che tutto ciò che fa è rendere una pagina di testo (è solo un componente con una funzione di rendering), tuttavia sto pensando di creare un'app enorme con oltre 70 percorsi - alcuni dei quali essere pagine semplici e altre sarebbero cose più complesse e gigantesche che tirano dentro un mucchio di dipendenze, quindi voglio capire prima questa cosa asincrona prima di andare oltre. Stavo pensando che forse potrei creare un componente wrapper che invece esegue il caricamento asincrono, ma non sembra il modo "giusto" per farlo. –