react-router 中的history
react-router 中的history
趙飛 Coding/旅行✈️react-router是建立在history之上的;我們來談談這個history吧。
github:mjackson/history
history 一個管理js應用session會話歷史的js庫。它將不同環境(瀏覽器,node...)的變數統一成了一個簡易的API來管理歷史堆疊、導航、確認跳轉、以及sessions間的持續狀態。
//基本 使用
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
// 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。它使用HistoryAPI 在瀏覽器中被建立用於處理 URL,新建一個像這樣真實的`URL example.com/some/path`
伺服器配置
首先伺服器應該能夠處理 URL 請求。處理應用啟動最初的 / 這樣的請求應該沒問題,但當用戶來回跳轉並在 /accounts/123 重新整理時,伺服器就會收到來自 /accounts/123 的請求,這時你需要處理這個 URL 並在響應中包含 JavaScript 程式程式碼。
一個 express 的應用可能看起來像這樣的:
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,請使用try_files directive:
server {
...
location / {
try_files $uri /index.html
}
}
當在伺服器上找不到其他檔案時,這就會讓 nginx 伺服器生成靜態檔案和操作 index.html 檔案。
createMemoryHistory
Memory history 不會在位址列被操作或讀取。這就解釋了我們是如何實現伺服器渲染的。同時它也非常適合測試和其他的渲染環境(像 React Native )。
實現示例
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')
)
編輯於 2016-05-27 18:35
前端開發
React
前端工程師