react-router 是建立在 History 之上的。
History 一个管理 js 应用 session 会话历史的 js 库。它将不同环境(浏览器,node…)的变量统一成了一个简易的 API 来管理历史堆栈、导航、确认跳转、以及 sessions 间的持续状态。
History 的 Github 仓库如下:
Github: mjackson/history
使用入门
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import { createHistory } from 'history'
const history = createHistory()
const location = history.getCurrentLocation()
const unlisten = history.listen(location => { console.log(location.pathname) })
history.push({ pathname: '/the/path', search: '?a=query',
state: { the: 'state' } })
unlisten()
|
你也可以使用 history 对象来的方法来改变当前的location:
- push(location)
- replace(location)
- go(n)
- goBack()
- goForward()
一个 history 知道如何去监听浏览器地址栏的变化, 并解析这个 URL 转化为 location 对象, 然后 router 使用它匹配到路由,最后正确地渲染对应的组件。
location对象包括:
pathname
同window.location.pathname
search
同window.location.search
state
一个捆绑在这个地址上的object对象
action
PUSH, REPLACE, 或者 POP中的一个
key
唯一ID
常用的三种history
1 2 3 4 5 6 7 8
| import createHistory from 'history/lib/createBrowserHistory'
import createHistory from 'history/lib/createHashHistory'
import createHistory from 'history/lib/createMemoryHistory'
|
createHashHistory
这是一个你会获取到的默认 history ,如果你不指定某个 history (即 <Router>{/* your routes */}</Router>
)。它用到的是 URL 中的 hash(#)部分去创建形如 example.com/#/some/path
的路由。
Hash history 是默认的,因为它可以在服务器中不作任何配置就可以运行,并且它在全部常用的浏览器包括 IE8+ 都可以用。但是我们不推荐在实际生产中用到它,因为每一个 web 应用都应该有目的地去使用 createBrowserHistory。
createBrowserHistory
Browser history 是由 React Router 创建浏览器应用推荐的 history。它使用 History API 在浏览器中被创建用于处理 URL,新建一个像这样真实的 URL example.com/some/path
服务器配置
首先服务器应该能够处理 URL 请求。处理应用启动最初的 /
这样的请求应该没问题,但当用户来回跳转并在 /accounts/123
刷新时,服务器就会收到来自 /accounts/123
的请求,这时你需要处理这个 URL 并在响应中包含 JavaScript 程序代码。
express
一个 express 的应用可能看起来像这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const express = require('express') const path = require('path') const port = process.env.PORT || 8080 const app = express()
app.use(express.static(__dirname + '/public'))
app.get('*', function (request, response){ response.sendFile(path.resolve(__dirname, 'public', 'index.html')) })
app.listen(port) console.log("server started on port " + port)
|
nginx
如果你的服务器是 nginx,请使用 try_files directive:
1 2 3 4 5 6
| server { ... location / { try_files $uri /index.html } }
|
当在服务器上找不到其他文件时,这就会让 nginx 服务器生成静态文件和操作 index.html 文件。
createMemoryHistory
Memory history 不会在地址栏被操作或读取。这就解释了我们是如何实现服务器渲染的。同时它也非常适合测试和其他的渲染环境(像 React Native )。
实现示例
jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import React from 'react' import createBrowserHistory from 'history/lib/createBrowserHistory' import { Router, Route, IndexRoute } from 'react-router' import App from '../components/App' import Home from '../components/Home' import About from '../components/About' import Features from '../components/Features'
React.render( <Router history={createBrowserHistory()}> <Route path='/' component={App}> <IndexRoute component={Home} /> <Route path='about' component={About} /> <Route path='features' component={Features} /> </Route> </Router>, document.getElementById('app') )
|
记录浏览历史
jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import React from 'react' import createBrowserHistory from 'history/lib/createBrowserHistory' import { Router, Route, IndexRoute } from 'react-router' import App from '../components/App' import Home from '../components/Home' import About from '../components/About' import Features from '../components/Features'
const appHistory = createBrowserHistory(); let url = '';
appHistory.listen((event) => { const location = event.location.pathname; if (location !== url ) { console.log(`visited ${location}`); url = location; } });
React.render( <Router history={createBrowserHistory()}> <Route path='/' component={App}> <IndexRoute component={Home} /> <Route path='about' component={About} /> <Route path='features' component={Features} /> </Route> </Router>, document.getElementById('app') )
|
欢迎关注我的公众号 须弥零一,跟我一起学习IT知识。
如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !