history
是一个用来管理历史会话的一个JS包。对于不同环境history
提供了统一的API,用于用来管理历史堆栈(history stack)、导航,导航确认、持久化状态。
这段话翻译过来可能比较难懂,可以对比浏览器端原生的history对象来理解它的功能。对于浏览器端,其实就是对原生history对象进行再封装。
Installation
$ npm install --save history
如果使用了类似webpack的打包工具,通过如下示例使用:
// using ES6 modules
import createHistory from 'history/createBrowserHistory'
// using CommonJS modules
var createHistory = require('history').createBrowserHistory
或者直接引入,通过window.History
引用:<script src="https://unpkg.com/history/umd/history.min.js"></script>
Usage
根据不同环境,history
包提供了三种创建history
对象的方法:
createBrowserHistory
用于支持HTML5 history API的现代浏览器.(查看浏览器兼容性)createMemoryHistory
用于非DOM环境,比如React Native或用于测试。createHashHistory
用于传统的浏览器。
可以通过使用import
(或require
)在包目录下引用(i.e.history/createBrowserHistory
)。
以下文档使用createHistory
术语代表以上三个方法的实现。
基础用法示例:
import createHistory from 'history/createBrowserHistory'
const history = createHistory()
// Get the current location.
const location = history.location
// Listen for changes to the current location.
const unlisten = history.listen((location, action) => {
// location is an object like window.location
console.log(action, location.pathname, location.state)
})
// Use push, replace, and go to navigate around.
history.push('/home', { some: 'state' })
// To stop listening, call the function returned from listen().
unlisten()
以下代码展示了每个create
方法的参数以及对应的默认值,具体每个参数的作用后面详细介绍。
createBrowserHistory({
basename: "", // The base URL of the app (see below)
forceRefresh: false, // Set true to force full page refreshes
keyLength: 6, // The length of location.key
// A function to use to confirm navigation with the user (see below)
getUserConfirmation: (message, callback) => callback(window.confirm(message))
})
createMemoryHistory({
initialEntries: ["/"], // The initial URLs in the history stack
initialIndex: 0, // The starting index in the history stack
keyLength: 6, // The length of location.key
// A function to use to confirm navigation with the user. Required
// if you return string prompts from transition hooks (see below)
getUserConfirmation: null
})
createHashHistory({
basename: "", // The base URL of the app (see below)
hashType: "slash", // The hash type to use (see below)
// A function to use to confirm navigation with the user (see below)
getUserConfirmation: (message, callback) => callback(window.confirm(message))
})
Properties
每种history
对象都具有如下属性:
history.length
- The number of entries in the history stackhistory.location
- The current locationhistory.action
- The current navigation action
除此之外,createMemoryHistory
还提供了history.index
和history.entries
属性,可以同来审查history stack.
Listening
通过history.listen
监听当前地址变化。
history.listen((location, action) => {
console.log(
`The current URL is ${location.pathname}${location.search}${location.hash}`
)
console.log(`The last navigation action was ${action}`)
})
location
对象实现了window.location接口的子集,包括:
location.pathname
- The path of the URLlocation.search
- The URL query stringlocation.hash
- The URL hash fragment
并且还具有如下属性:
location.state
- 和当前地址相关的,且不需要包含在URL中的状态值(createBrowserHistory
和createMemoryHistory
支持)location.key
- 代表当前地址的唯一值(string类型)(createBrowserHistory
和createMemoryHistory
支持)
action
为PUSH
、REPLACE
、POP
其中之一,取决于用户如何访问的当前URL。
Navigation
可以通过如下方法,以编程的方式改变当前地址:
- history.push(path, [state])
- history.replace(path, [state])
- history.go(n)
- history.goBack()
- history.goForward()
- history.canGo(n) (仅
createMemoryHistory
支持)
当使用push
或replace
时,支持两种参数形式:
- 传入必需的path参数和可选的state参数。
- 传入一个类location对象:
{ pathname , search , hash , state }
。
// Push a new entry onto the history stack.
history.push("/home")
// Push a new entry onto the history stack with a query string
// and some state. Location state does not appear in the URL.
history.push("/home?the=query", { some: "state" })
// If you prefer, use a single location-like object to specify both
// the URL and state. This is equivalent to the example above.
history.push({
pathname: "/home",
search: "?the=query",
state: { some: "state" }
})
// Go back to the previous history entry. The following
// two lines are synonymous.
history.go(-1)
history.goBack()
注意: 仅 createBrowserHistory
和 createMemoryHistory
支持location state。
Blocking Transitions
history
支持注册一个提示信息,会在通知history.listen()
回调之前进行展示。
从而可以实现在用户离开当前页面之前提示用户是否要离开。
// Register a simple prompt message that will be shown the
// user before they navigate away from the current page.
const unblock = history.block("Are you sure you want to leave this page?")
// Or use a function that returns the message when it's needed.
history.block((location, action) => {
// The location and action arguments indicate the location
// we're transitioning to and how we're getting there.
// A common use case is to prevent the user from leaving the
// page if there's a form they haven't submitted yet.
if (input.value !== "") return "Are you sure you want to leave this page?"
})
// To stop blocking transitions, call the function returned from block().
unblock()
注意: 在createMemoryHistory
中使用此功能需要提供getUserConfirmation
函数。(见下文)
Customizing the Confirm Dialog
默认情况下,使用window.confirm
向用户展示提示信息。在创建history对象时提供getUserConfirmation
函数,可以覆盖该默认行为。(或者使用createMemoryHistory
时,该方法会假定不存在DOM环境)。
const history = createHistory({
getUserConfirmation(message, callback) {
// Show some custom dialog to the user and call
// callback(true) to continue the transiton, or
// callback(false) to abort it.
}
})
Using a Base URL
如果在应用中所有URL都相对于一个"基本"URL,则可以使用basename
参数。
const history = createHistory({
basename: "/the/base"
})
history.listen(location => {
console.log(location.pathname) // /home
})
history.push("/home") // URL is now /the/base/home
注意: createMemoryHistory
不支持 basename
Forcing Full Page Refreshes in createBrowserHistory
默认情况下,createBrowserHistory
使用HTML的pushState
和replaceState
来防止在导航时刷新整个页面。如果想要在URL变化时,重新加载页面,可以使用forceRefresh
参数。
const history = createBrowserHistory({
forceRefresh: true
})
Modifying the Hash Type in createHashHistory
默认情况下,createHashHistory
以"#/"
的形式展示路径。可以通过hashType
参数更改。
const history = createHashHistory({
hashType: "slash" // the default
})
history.push("/home") // window.location.hash is #/home
const history = createHashHistory({
hashType: "noslash" // Omit the leading slash
})
history.push("/home") // window.location.hash is #home
const history = createHashHistory({
hashType: "hashbang" // Google's legacy AJAX URL format
})
history.push("/home") // window.location.hash is #!/home
About
history
is developed and maintained by React Training. If
you're interested in learning more about what React can do for your company, please
get in touch!