Un moyen d'empêcher /#/
de s'afficher dans la barre d'adresse du navigateur lors de l'utilisation de react-router? C'est avec ReactJS. En d'autres termes, cliquer sur les liens pour accéder à un nouvel itinéraire affiche localhost:3000/#/
ou localhost:3000/#/about
. En fonction de l'itinéraire.
Pour les versions 1, 2 et 3 de react-router, la méthode appropriée pour définir l'itinéraire vers un schéma de mappage d'URL consiste à transmettre une implémentation d'historique au paramètre history
de <Router>
. De la documentation d'histoires :
En résumé, un historique sait comment écouter les modifications apportées à la barre d'adresse du navigateur et analyse l'URL dans un objet d'emplacement que le routeur peut utiliser pour faire correspondre les itinéraires et restituer le bon ensemble de composants.
Dans react-router 2 et 3, le code de configuration de votre route ressemblera à ceci:
import { browserHistory } from 'react-router'
ReactDOM.render ((
<Router history={browserHistory} >
...
</Router>
), document.body);
Dans la version 1.x, vous utiliserez plutôt les éléments suivants:
import createBrowserHistory from 'history/lib/createBrowserHistory'
ReactDOM.render ((
<Router history={createBrowserHistory()} >
...
</Router>
), document.body);
Source: Guide de mise à jour version 2.
Pour la prochaine version 4 de react-router, la syntaxe a beaucoup changé et il est nécessaire d'utiliser BrowserRouter
comme balise racine du routeur.
import BrowserRouter from 'react-router/BrowserRouter'
ReactDOM.render ((
<BrowserRouter>
...
<BrowserRouter>
), document.body);
Router.run(routes, Router.HistoryLocation, function (Handler) {
React.render(<Handler/>, document.body);
});
Pour la version 0.11 actuelle et ultérieure, vous devez ajouter Router.HistoryLocation
à Router.run()
. <Routes>
sont maintenant obsolètes. Voir le Guide de mise à nivea pour l'implémentation de 0.12.x HistoryLocation.
Si vous n'avez pas besoin de supporter IE8, vous pouvez utiliser l'historique du navigateur et react-router utilisera window.pushState
au lieu de définir le hachage.
Cela dépend de la version de React Router que vous utilisez:
Vous pouvez réellement utiliser .htaccess pour accomplir cela. Le navigateur a normalement besoin du délimiteur de chaîne de requête ?
ou #
pour déterminer le début de la chaîne de requête et la fin des chemins de répertoire. Le résultat final que nous voulons est www.mysite.com/dir
Il nous faut donc résoudre le problème avant que le serveur Web ne recherche le répertoire pour lequel nous pensons avoir demandé /dir
. Nous plaçons donc un fichier .htaccess
à la racine du projet.
# Setting up Apache options
AddDefaultCharset utf-8
Options +FollowSymlinks -MultiViews -Indexes
RewriteEngine on
# Setting up Apache options (Godaddy specific)
#DirectoryIndex index.php
#RewriteBase /
# Defining the rewrite rules
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^.*$ ./index.html
Ensuite, vous obtenez les paramètres de requête avec window.location.pathname
Vous pouvez ensuite éviter d'utiliser des itinéraires réactifs si vous le souhaitez et manipuler simplement l'URL et l'historique du navigateur si vous le souhaitez également. J'espère que ça aide quelqu'un ...
Installer le paquet d'historique
npm install history --save
Importation suivante de createHistory et de useBasename de l'historique
import { createHistory, useBasename } from 'history';
...
const history = useBasename(createHistory)({
basename: '/root'
});
si l'URL de votre application est www.example.com/myApp, alors/root doit être/myApp.
transmettre la variable d'historique au routeur
render((
<Router history={history}>
...
</Router>
), document.getElementById('example'));
Maintenant, pour toutes vos balises Link, ajoutez un "/" devant tous les chemins.
<Link to="/somewhere">somewhere</Link>
L'inspiration de la solution est venue de exemple de React-Router Ce qui, malheureusement, n'a pas été correctement documenté dans leur API.
Une autre façon de gérer les éléments à afficher après le hachage (donc si vous n'utilisez pas pushState!) Consiste à créer votre CustomLocation et à le charger lors de la création de ReactRouter.
Par exemple, si vous voulez avoir l'URL hashbang (donc avec #!) Pour se conformer aux spécifications de Google pour l'analyse, vous pouvez créer un fichier HashbangLocation.js qui copie principalement le HashLocation d'origine, tel que:
'use strict';
var LocationActions = require('../../node_modules/react-router/lib/actions/LocationActions');
var History = require('../../node_modules/react-router/lib/History');
var _listeners = [];
var _isListening = false;
var _actionType;
function notifyChange(type) {
if (type === LocationActions.Push) History.length += 1;
var change = {
path: HashbangLocation.getCurrentPath(),
type: type
};
_listeners.forEach(function (listener) {
listener.call(HashbangLocation, change);
});
}
function slashToHashbang(path) {
return "!" + path.replace(/^\//, '');
}
function ensureSlash() {
var path = HashbangLocation.getCurrentPath();
if (path.charAt(0) === '/') {
return true;
}HashbangLocation.replace('/' + path);
return false;
}
function onHashChange() {
if (ensureSlash()) {
// If we don't have an _actionType then all we know is the hash
// changed. It was probably caused by the user clicking the Back
// button, but may have also been the Forward button or manual
// manipulation. So just guess 'pop'.
var curActionType = _actionType;
_actionType = null;
notifyChange(curActionType || LocationActions.POP);
}
}
/**
* A Location that uses `window.location.hash`.
*/
var HashbangLocation = {
addChangeListener: function addChangeListener(listener) {
_listeners.Push(listener);
// Do this BEFORE listening for hashchange.
ensureSlash();
if (!_isListening) {
if (window.addEventListener) {
window.addEventListener('hashchange', onHashChange, false);
} else {
window.attachEvent('onhashchange', onHashChange);
}
_isListening = true;
}
},
removeChangeListener: function removeChangeListener(listener) {
_listeners = _listeners.filter(function (l) {
return l !== listener;
});
if (_listeners.length === 0) {
if (window.removeEventListener) {
window.removeEventListener('hashchange', onHashChange, false);
} else {
window.removeEvent('onhashchange', onHashChange);
}
_isListening = false;
}
},
Push: function Push(path) {
_actionType = LocationActions.Push;
window.location.hash = slashToHashbang(path);
},
replace: function replace(path) {
_actionType = LocationActions.REPLACE;
window.location.replace(window.location.pathname + window.location.search + '#' + slashToHashbang(path));
},
pop: function pop() {
_actionType = LocationActions.POP;
History.back();
},
getCurrentPath: function getCurrentPath() {
return decodeURI(
// We can't use window.location.hash here because it's not
// consistent across browsers - Firefox will pre-decode it!
"/" + (window.location.href.split('#!')[1] || ''));
},
toString: function toString() {
return '<HashbangLocation>';
}
};
module.exports = HashbangLocation;
Notez la fonction slashToHashbang.
Ensuite, il suffit de faire
ReactRouter.create({location: HashbangLocation})
Et c'est tout :-)