Notez que cette réponse couvre la version 0.13.x de React Router - la prochaine version 1.0 semble avoir des détails d'implémentation très différents
Serveur
C'est un minimum server.js
avec 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})
})
})
Où le routes
module exporte une liste de routes:
var React = require('react')
var {DefaultRoute, NotFoundRoute, Route} = require('react-router')
module.exports = [
<Route path="/" handler={require('./components/App')}>
{/* ... */}
</Route>
]
Chaque fois qu'une demande est faite au serveur, vous créez une Router
instance à usage unique configurée avec l'URL entrante comme emplacement statique, qui est résolue par rapport à l'arborescence des routes pour configurer les routes correspondantes appropriées, en rappelant avec le niveau supérieur gestionnaire de route à rendre et un enregistrement des routes enfants correspondant à chaque niveau. C'est ce qui est consulté lorsque vous utilisez le <RouteHandler>
composant dans un composant de gestion d'itinéraire pour rendre un itinéraire enfant qui a été mis en correspondance.
Si l'utilisateur a désactivé JavaScript ou que son chargement est lent, tous les liens sur lesquels il clique atteindront à nouveau le serveur, ce qui est résolu à nouveau comme ci-dessus.
Client
C'est un minimum client.js
avec react-router (réutiliser le même module routes):
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)
})
Lorsque vous appelez Router.run()
, il crée une instance de routeur pour vous dans les coulisses, qui est réutilisée chaque fois que vous naviguez dans l'application, car l'URL peut être dynamique sur le client, par opposition au serveur où une seule demande a un URL fixe.
Dans ce cas, nous utilisons le HistoryLocation
, qui utilise l' History
API pour nous assurer que la bonne chose se passe lorsque vous appuyez sur le bouton Précédent / Suivant. Il y a aussi un HashLocation
qui change l'URL hash
pour faire des entrées d'historique et écoute l' window.onhashchange
événement pour déclencher la navigation.
Lorsque vous utilisez le <Link>
composant de react-router , vous lui donnez un to
accessoire qui est le nom d'une route, plus les données params
et query
les besoins de la route. Le <a>
rendu par ce composant a un onClick
gestionnaire qui appelle finalement router.transitionTo()
l'instance de routeur avec les accessoires que vous avez donnés au lien, qui ressemble à ceci:
/**
* 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);
}
},
Pour un lien régulier, cela appelle finalement location.push()
le type d'emplacement que vous utilisez, qui gère les détails de la configuration de l'historique afin que la navigation avec les boutons Précédent et Suivant fonctionnera, puis rappelle à router.handleLocationChange()
pour informer le routeur qu'il peut procéder à la transition vers le nouveau chemin d'URL.
Le routeur appelle ensuite sa propre router.dispatch()
méthode avec la nouvelle URL, qui gère les détails pour déterminer laquelle des routes configurées correspond à l'URL, puis appelle tous les hooks de transition présents pour les routes correspondantes. Vous pouvez implémenter ces hooks de transition sur n'importe lequel de vos gestionnaires d'itinéraire pour prendre des mesures lorsqu'une route est sur le point d'être parcourue ou parcourue, avec la possibilité d'annuler la transition si les choses ne vous conviennent pas.
Si la transition n'a pas été abandonnée, la dernière étape consiste à appeler le rappel que vous avez donné Router.run()
avec le composant de gestionnaire de niveau supérieur et un objet d'état avec tous les détails de l'URL et les routes correspondantes. Le composant de gestionnaire de niveau supérieur est en fait l' Router
instance elle-même, qui gère le rendu du gestionnaire de route le plus haut correspondant.
Le processus ci-dessus est réexécuté chaque fois que vous accédez à une nouvelle URL sur le client.
Exemples de projets