React-router中的History

如何在React-router中使用History

Posted by Jeremy Song on 2023-03-05
Estimated Reading Time 5 Minutes
Words 1.2k In Total
Viewed Times

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',

// 一些不存在url参数上面的当前url的状态值
state: { the: 'state' }
})

// When you're finished, stop the listener
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
// HTML5 history, 推荐
import createHistory from 'history/lib/createBrowserHistory'

// Hash history
import createHistory from 'history/lib/createHashHistory'

// 内存 history (如:node环境)
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'))

// 在你应用 JavaScript 文件中包含了一个 script 标签
// 的 index.html 中处理任何一个 route
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 )。

实现示例

jsx
1
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')
)

记录浏览历史

jsx
1
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 ) {
// record log here
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知识。


如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !