一、如何找到文档
在 GitHub 上直接搜索 react-router 进入,就能找到开发文档,
这里可以提供下,链接:https://reacttraining.com/react-router/
现在路由都是使用 react-router-dom 了。
二、路由容器
这个和以前 3.0 版本的路由配置不一样了,现在路由对应两种模式提供两个路由容器。
- hashhistory
import { HashRouter as Router } from "react-router-dom";
- browerhistory
import { BrowserRouter as Router } from "react-router-dom";
Vue 就一个路由容器 <router-view />
三、如何放置路由
react-router-dom 书写的路由方式是声明式,可以说是非常的难用,所以一般都是封装成类似 vue-router 路由书写方式。
<Router>
<div>
<Route path="/" render={() => <Child component={App} />} ></Route>
<Route path="/" component={A} ></Route>
<Route path="/" children={()=><A/>} ></Route>
children为函数时不管path匹不匹配都会显示组件,如果不是函数显示效果和component相同
</div>
</Router>
路由书写优先级为 component > render > children
四、路由跳转和传参
类似 Vue 中的 this.$router,react 路由参数主要包含四部分:
- history里面有push
- location 有query(search)和params(state)
location内容
{
hash: ""
pathname: "/about"
search: ""
state: {id: 10}
}
- match配置路由路径
- staticContext
路由跳转的两种方式:
- 声明式
<Link to="/about?user=CondorHero">关于</Link>
<Link to={{pathname:"/about",search:"CondorHero"}}>关于</Link>
<Link to={{pathname:"/about",state:{id:10}}}>关于</Link>
比较特殊的还有一个 NavLink 导航链接,不同于 Link ,NavLink 可以增加样式。常用于单页面左侧导航。
<NavLink to="/about" style={{fontWeight: "bold",color: "red"}}>About</NavLink>
<NavLink to="/about" activeClassName="className">About</NavLink>
元素处于活动状态时应用于元素的样式, 可以行内也可以类名添加活动样式。
- 编程式
push方法,两种配置方式能够 push ,一种是 <Route></Route> 包裹的组件,通过 this.props.history.push
另一种是通过,history 模块,或者是 useHistory 钩子。
五、重定向
新位置将覆盖历史记录堆栈中的当前位置,就像服务器端重定向(HTTP 3xx)一样。
import { Redirect } from "react-router-dom";
<Redirect to="/somewhere/else" />
//用法和Link一样
六、如何在任意组件找到 Vue this 上的路由对象
Vue 2.0 的路由是绑定在 this 的身上,React 路由只会出现在 和 <Route></Route>
绑定的组件内部,所以其他组件要想跳转路由并传参的话,两种办法。
- history
注意⚠️这个 history 不是浏览器原生的。
import { createBrowserHistory , createHashHistory } from "history";
const customHistory = createBrowserHistory();
console.log(customHistory)
- withRouter
import { withRouter } from "react-router-dom";
function Main(props){
console.log(props)
return (
<div>
<h1>你好</h1>
</div>
)
}
const A = withRouter(Main);
/*A仍然作为组件使用*/
<A></A>
七、路由钩子
这个路由钩子不是路由守卫,React-router 脑残,在 4.0 把路由拦截给删了,这里出现的路由钩子完全是针对 react-hook而言的路由hooks。react 版本要求大于 16.8。
- useHistory
import { useHistory } from "react-router-dom";
const history = useHistory();
history.push({pathname:"/index"})
- useParams
useParams返回URL参数的键/值对的对象。使用它来访问match.params当前<Route>,所以只对:
<Route path="/about/:slug" component={A} ></Route>
组件有效,push 或 params 携带参数都不行。
- useLocation
该useLocation挂钩返回location代表当前URL 的对象。
重点:配合 useEffect 可作为局部组件守卫使用。
- useRouteMatch
八、回到顶部
:root{
scroll-behavior:smooth;
}
window.scrollTo(0,0);
九、路由精确匹配问题
react 路由默认是模糊匹配,例如:
<Route path="/" render={() => <B />} ></Route>
<Route path="/index" render={() => <index />} ></Route>
<Route path="/:user" render={() => <User />} ></Route>
输入 index 三个路径都会匹配。路由添加 exact(精确)属性可以精确匹配。必须是路径和大小写一样。
还有一个组件是 switch ,组件内部采用模糊匹配,但是只会匹配一个路由。
<Switch>
<Route path="/" exact render={() => <B />} ></Route>
<Route path="/index" render={() => <index />} ></Route>
<Route path="/:user" render={() => <User />} ></Route>
</Switch>
十、静态化路由
相信你也发现了,嵌套路由写起来麻烦维护起来也麻烦。就没有类似 vue-router 那样数组的写法吗。还真没有需要自己来实现。但是官方也维护一个未来版 react-router-config 。不过实在是太简陋了。
一个简单的用法示例:
相对 Vue-Router 来讲:
- 这个routes就相当于children
- {renderRoutes(this.props.route.routes)} 就相当于 router-view
class B extends React.Component {
constructor(props) {
super(props);
this.route = this.props.route;
}
render() {
return (
<div>
<h1>B</h1>
{renderRoutes(this.route.routes)}
</div>
)
}
}
class Root extends React.Component {
constructor(props) {
super(props);
this.route = this.props.route;
}
render() {
return (
<div>
<h1>我是Root组件</h1>
{renderRoutes(this.route.routes)}
<h1>我是Root组件</h1>
</div>
)
}
}
class Index extends React.Component {
constructor(props) {
super(props);
this.route = this.props.route;
}
render() {
return (
<div>
<h2>我是Index组件</h2>
{renderRoutes(this.props.route.routes,{ someProp: "these extra props are optional" })}
</div>
)
}
}
class Child extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h3>我是child组件</h3>
{renderRoutes(this.props.route.routes,{ someProp: "these extra props are optional" })}
<h3>我是child组件</h3>
</div>
)
}
}
const routes = [
{
component: Root,
routes: [
{
path: "/",
exact: true,
component: Index
},
{
path:"/B",
component:B,
routes: [
{
path: "/B/child",
component: Child
}
]
}
]
}
];
ReactDOM.render(
<React.StrictMode>
<Router>
<div>
{renderRoutes(routes)}
</div>
</Router>
</React.StrictMode>,
document.getElementById('root')
);
最后
还有一个知识点:PureComponent 和 Component 的区别?
PureComponent 只会在 state 和 props 不同才会更新。
参考:React 的 PureComponent Vs Component
当前时间 2020年5月5日 星期二 13:22:52
网友评论