Nota, questa risposta copre la versione 0.13.x di React Router: la prossima versione 1.0 sembra che avrà dettagli di implementazione significativamente diversi
server
Questo è un minimo server.js
con React-Router:
var express = require('express')
var React = require('react')
var Router = require('react-router')
var routes = require('./routes')
var app = express()
// ...express config...
app.use(function(req, res, next) {
var router = Router.create({location: req.url, routes: routes})
router.run(function(Handler, state) {
var html = React.renderToString(<Handler/>)
return res.render('react_page', {html: html})
})
})
Dove il routes
modulo esporta un elenco di rotte:
var React = require('react')
var {DefaultRoute, NotFoundRoute, Route} = require('react-router')
module.exports = [
<Route path="/" handler={require('./components/App')}>
{/* ... */}
</Route>
]
Ogni volta che viene effettuata una richiesta al server, si crea Router
un'istanza monouso configurata con l'URL in entrata come posizione statica, che viene risolta rispetto all'albero delle rotte per impostare le rotte corrispondenti appropriate, richiamando con il livello superiore gestore delle rotte di cui eseguire il rendering e una registrazione delle rotte secondarie corrispondenti a ciascun livello. Questo è ciò che viene consultato quando usi il file<RouteHandler>
componente all'interno di un componente di gestione delle rotte per eseguire il rendering di una rotta figlio che è stata abbinata.
Se l'utente ha disattivato JavaScript o il caricamento è lento, qualsiasi collegamento su cui fa clic raggiungerà nuovamente il server, il che verrà risolto nuovamente come sopra.
Cliente
Questo è un minimo client.js
con React-Router (riutilizzo dello stesso modulo route):
var React = require('react')
var Router = require('react-router')
var routes = require('./routes')
Router.run(routes, Router.HistoryLocation, function(Handler, state) {
React.render(<Handler/>, document.body)
})
Quando chiami Router.run()
, crea un'istanza del router dietro le quinte, che viene riutilizzata ogni volta che navighi nell'app, poiché l'URL può essere dinamico sul client, invece che sul server in cui una singola richiesta ha un URL fisso.
In questo caso, stiamo usando HistoryLocation
, che utilizza l' History
API per assicurarci che accada la cosa giusta quando premi il pulsante Indietro / Avanti. C'è anche un HashLocation
che cambia l'URL hash
per inserire voci nella cronologia e ascolta l' window.onhashchange
evento per attivare la navigazione.
Quando usi il <Link>
componente di react-router , gli dai un to
prop che è il nome di una rotta, più qualsiasi dato params
e di cui ha query
bisogno la rotta. Il <a>
rendering da questo componente ha un onClick
gestore che alla fine chiama router.transitionTo()
l'istanza del router con gli oggetti di scena che hai fornito al collegamento, che assomiglia a questo:
/**
* Transitions to the URL specified in the arguments by pushing
* a new URL onto the history stack.
*/
transitionTo: function (to, params, query) {
var path = this.makePath(to, params, query);
if (pendingTransition) {
// Replace so pending location does not stay in history.
location.replace(path);
} else {
location.push(path);
}
},
Per un collegamento normale, questo alla fine chiama location.push()
il tipo di posizione che stai utilizzando, che gestisce i dettagli della configurazione della cronologia, quindi la navigazione con i pulsanti Indietro e Avanti funzionerà, quindi richiama per router.handleLocationChange()
far sapere al router che può procedere con la transizione a il nuovo percorso URL.
Il router chiama quindi il proprio router.dispatch()
metodo con il nuovo URL, che gestisce i dettagli per determinare quale delle rotte configurate corrisponde all'URL, quindi chiama eventuali hook di transizione presenti per le rotte corrispondenti. Puoi implementare questi hook di transizione su qualsiasi gestore di rotta per intraprendere un'azione quando una rotta sta per essere spostata o verso di essa, con la possibilità di interrompere la transizione se le cose non sono di tuo gradimento.
Se la transizione non è stata interrotta, il passaggio finale consiste nel richiamare il callback a cui hai fornito Router.run()
il componente gestore di primo livello e un oggetto di stato con tutti i dettagli dell'URL e le rotte corrispondenti. Il componente gestore di primo livello è in realtà l' Router
istanza stessa, che gestisce il rendering del gestore di rotte più in alto che è stato abbinato.
Il processo di cui sopra viene rieseguito ogni volta che si accede a un nuovo URL sul client.
Progetti di esempio