React路由
React路由原理
- HashRouter:利用hash实现路由切换
- BrowserRouter:实现h5 Api实现路由的切换
history
- history对象提供了操作浏览器会话历史的接口。
- pushState HTML5引入了 history.pushState() 和 history.replaceState() 方法,它们分别可以添加和修改历史记录条目。这些方法通常与window.onpopstate配合使用
- onpopstate window.onpopstate是popstate事件在window对象上的事件处理程序
history.pushState
history.pushState( state,title,url )
- pushState会往History中写入一个对象,他造成的结果便是,History length +1、url 改变、该索引History对应有一个State对象,这个时候若是点击浏览器的后退,便会触发popstate事件,将刚刚的存入数据对象读出
- 每次我们会根据State的信息还原当前的view,于是用户点击后退便有了与浏览器后退前进一致的感受
封装window.onpushstate
window上没有onpushstate事件函数 需要自己封装。
; (function (history) {
let pushState = history.pushState;
history.pushState = function (state, title, url) {
if (typeof window.onpushstate == 'function') {
window.onpushstate({
state, title, url
})
}
pushState.apply(history, arguments);
}
})(window.history);
Route渲染的三种方式
- component 简单,但是不能传参数,也不能渲染逻辑
- 传递一个render方法,也是看路径是否匹配,如果路径匹配的话就渲染render方法的返回值,
- 传递children方法。如果路径不匹配并且有children或者路径匹配只有children,就渲染。
跑通React路由
index.tsx
Router有且只有一个子组件。
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { HashRouter as Router, Route } from 'react-router-dom';
import Home from './components/Home';
import User from './components/User';
import Prefile from './components/Prefile';
ReactDOM.render(
<Router>
<div>
<Route path="/" component={Home} />
<Route path="/user" component={User} />
<Route path="/prefile" component={Prefile} />
</div>
</Router>,
document.getElementById('root')
)
components/Home.tsx
import React, { Component } from 'react'
import { RouteComponentProps } from 'react-router-dom'
type Props = RouteComponentProps & {
};
export default class Home extends Component<Props>{
constructor(props) {
super(props);
console.log(this.props.history);
}
render() {
return (
<div>
home
</div>
)
}
}
components/User.tsx
import React, { Component } from 'react'
export default class User extends Component {
render() {
return (
<div>
User
</div>
)
}
}
components/prefile.tsx
import React, { Component } from 'react'
export default class prefile extends Component {
constructor(props) {
super(props);
console.log(this.props);
}
render() {
return (
<div>
prefile
</div>
)
}
}