Answers:
对于react-router的版本1、2和3,将路由设置为URL映射方案的正确方法是将历史记录实现传递给history
参数<Router>
。从历史记录文档中:
简而言之,历史记录知道如何侦听浏览器的地址栏以进行更改,并将URL解析为一个位置对象,路由器可以使用该对象来匹配路由并呈现正确的组件集。
在react-router 2和3中,您的路由配置代码将如下所示:
import { browserHistory } from 'react-router'
ReactDOM.render ((
<Router history={browserHistory} >
...
</Router>
), document.body);
在版本1.x中,您将改为使用以下内容:
import createBrowserHistory from 'history/lib/createBrowserHistory'
ReactDOM.render ((
<Router history={createBrowserHistory()} >
...
</Router>
), document.body);
来源:2.0版升级指南
对于即将发布的react-router版本4,语法已进行了很大的更改,并且要求将其BrowserRouter
用作路由器根标签。
import BrowserRouter from 'react-router/BrowserRouter'
ReactDOM.render ((
<BrowserRouter>
...
<BrowserRouter>
), document.body);
history
是您需要安装的独立软件包。
browserHistory
v2.x中的版本:import { browserHistory } from 'react-router' <Router history={browserHistory} />
检查react-router升级指南
hashHistory
,是否有一种方法可以在最后消除这个查询参数?http://localhost:8080/#/dashboard?_k=yqwtyu
Router.run(routes, Router.HistoryLocation, function (Handler) {
React.render(<Handler/>, document.body);
});
对于当前版本0.11及更高版本,您需要添加Router.HistoryLocation
到Router.run()
。<Routes>
现在已弃用。有关 0.12.x HistoryLocation的实现,请参阅《升级指南》。
如果不需要支持IE8,则可以使用“浏览器历史记录”,然后使用react-router window.pushState
代替设置哈希。
具体如何执行取决于您使用的React Router版本:
<Routes location="history">
了所有的东西,一切正常,直到您在路上刷新浏览器为止,即localhost:3000/about
我收到404错误。这是预期的,我正在使用python -m SimpleHTTPServer 3000
吗?
/about
实际上会加载您的根页面/
。否则,您的服务器将尝试寻找匹配/about
且什么也找不到的路由(404)。我个人不使用python,但是您通常会找到用于/*
或/.*
-> /
有效的手动路线-否则它可能是html5Mode
服务器设置中的url。
您实际上可以使用.htaccess来完成此操作。浏览器通常需要查询字符串定界符?
或#
确定查询字符串在何处开始以及目录路径在何处结束。我们想要的最终结果是www.mysite.com/dir
因此,我们需要在Web服务器搜索它认为我们的目录之前捕获问题/dir
。因此,我们将.htaccess
文件放置在项目的根目录中。
# 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
然后使用window.location.pathname获取查询参数
然后,您可以根据需要避免使用react路由,并且也可以仅操纵url和浏览器历史记录。希望这可以帮助某人...
安装历史记录包
npm install history --save
接下来从历史记录中导入createHistory和useBasename
import { createHistory, useBasename } from 'history';
...
const history = useBasename(createHistory)({
basename: '/root'
});
如果您的应用程序网址是www.example.com/myApp,则/ root应该是/ myApp。
将历史记录变量传递给路由器
render((
<Router history={history}>
...
</Router>
), document.getElementById('example'));
现在,对于所有Link标记,在所有路径之前添加一个“ /”。
<Link to="/somewhere">somewhere</Link>
该解决方案的灵感来自于React-Router Example, 不幸的是,其API中并未对其进行正确记录。
处理哈希后显示的内容的另一种方法(因此,如果您不使用pushState!)是创建您的CustomLocation并在ReactRouter创建时将其加载。
例如,如果您想让hashbang网址(以#!开头)符合Google进行抓取的规范,则可以创建一个HashbangLocation.js文件,该文件主要复制原始的HashLocation,例如:
'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;
注意slashToHashbang函数。
那你就要做
ReactRouter.create({location: HashbangLocation})
就是这样:-)
HashHistory
isoBrowserHistory
。另请参见此问题,在此我将提供有关此主题的很多背景信息。