本文主要讲述react-router 4.0的常用方式和基础api
接入react-router
使用create-react-app创建好项目之后
$ # web项目安装react-router-dom依赖
$ npm i react-router-dom
在src/app.tsx使用react-router
首先展示一下基本使用示例
src/app.tsx
import React from 'react';
import { BrowserRouter as Router,Route, Link } from 'react-router-dom'
import './App.css';
//Home组件
const Home:React.FC = ()=>{
return (
<div>Home</div>
)
}
//List组件
const List:React.FC = ()=>{
return (
<div>List</div>
)
}
class App extends React.Component{
render() {
return (
<div className="App">
<Router>
<div>
<p><Link to="/">Home</Link></p>
<p><Link to="/list">List</Link></p>
</div>
<Route exact path='/' component={Home} />
<Route path='/list' component={List} />
</Router>
</div>
);
}
}
export default App;
下面是react-router的一些常用组件
BrowserRouter
使用HTML5历史记录API(pushState,replaceState和popstate事件)的来保持UI与URL同步。
<BrowserRouter
basename={optionalString}
forceRefresh={optionalBool}
getUserConfirmation={optionalFunc}
keyLength={optionalNumber} >
<App/>
</BrowserRouter>
-
属性:
- basename: string
所有locations的基本URL。如果应用程序从服务器上的子目录提供,则需要将其设置为子目录。正确格式的基础名称应该有一个主要的斜杠,但没有尾部斜线
<BrowserRouter basename="/calendar"/> <Link to="/today"/> //如此匹配到的路由是:'/calendar/today'- getUserConfirmation: (message:string,callback:(allowTransition:boolean)=>void)=>void
用于确认导航的功能。默认使用window.confirm,要配合组件使用
const getConfirmation = (message, callback) => { const allowTransition = window.confirm(message) callback(allowTransition) } <BrowserRouter getUserConfirmation={getConfirmation}/>- forceRefresh: boolean
如果为true,则路由器将在页面导航中使用全页刷新。 使用场景:在不支持HTML5历史记录API的浏览器中使用此功能
const supportsHistory = 'pushState' in window.history <BrowserRouter forceRefresh={!supportsHistory}/>- keyLength: number
location.key的长度。默认为6。
<BrowserRouter keyLength={12}/>
HashRouter
使用URL的哈希部分(即window.location.hash)的来保持UI与URL同步。
Hash history不支持location.key或location.state。
由于此技术仅用于支持旧版浏览器,因此建议将服务器配置为使用
import { HashRouter } from 'react-router-dom'
<HashRouter>
<App/>
</HashRouter>
-
属性
-
basename (同BrowserHistory)
-
getUserConfirmation(同BrowserHistory)
-
hashType: string 用于window.location.hash的编码类型。可用值为(默认值"slash"):
-
"slash": 创建一个hash值,例如:#/ and #/sunshine/lollipops
-
"noslash": 创建一个hash值,例如:# and #sunshine/lollipops
-
”hashbang“: 创建一个”ajax crawlable” (已被谷歌弃用) 例如:#!/ and #!/sunshine/lollipops
-
-
Link
路由跳转组件
如下代码点击Link组件将跳转至路由:'/about'
import { Link } from 'react-router-dom'
<Link to="/about">About</Link>
- to: string | object
链接到的路径名或位置。
<Link to="/courses"/>
// or
//该方法会在组件的props.location上追加相应的属性
<Link to={{
pathname: '/courses', //路由
search: '?sort=name', //params
hash: '#the-hash', //hash值
state: { fromDashboard: true } //state
}}/>
- replace: boolean
如果为true,单击链接将替换历史堆栈中的当前条目,而不是添加新条目。
<Link to="/courses" replace />
NavLink
一种特殊版本的,当与当前URL匹配时,将向渲染元素添加样式属性。
import { NavLink } from 'react-router-dom'
<NavLink to="/about">About</NavLink>
属性
- activeClassName: string 当前路由的class类名
<NavLink
to="/faq" activeClassName="selected"
>FAQs</NavLink>
- activeStyle: object
当元素处于活动状态时应用于元素的样式。
<NavLink
to="/faq" activeStyle={{
fontWeight: 'bold',
color: 'red' }} >FAQs</NavLink>
- exact:boolean
只有完全匹配当前path的时候才会触发活动状态
//只有路由是'/'的时候才会匹配,'/a'不会被匹配
<NavLink exact to="/" >Profile</NavLink>
- strict: boolean 当为真时,在确定位置是否与当前网址匹配时,将考虑位置路径名上的尾部斜线。
//如果在浏览器中输入''
<NavLink strict to="/events/" >Events</NavLink>
Redirect
渲染将导航到新位置。新位置将覆盖历史堆栈中的当前位置,如服务器端重定向(HTTP 3xx)。
import { Route, Redirect } from 'react-router'
<Route exact path="/" render={() => (
loggedIn ? ( <Redirect to="/dashboard"/>
) : ( <div>其他组件</div>)}/>
属性:
- to: string
要重定向到的地址。
<Redirect to="/somewhere/else"/>
- to: object
要重定向到的地址。
<Redirect to={{
pathname: '/login', //重定向的路由
search: '?utm=your+face', //路由参数(props.loaction.search)
state: { referrer: currentLocation } //往props.location.state上追加参数
}}/>
- push: boolean
当为true时,重定向会将新条目推入历史记录,而不是替换当前条目。
<Redirect push to="/somewhere/else"/>
- from: string
只有当当前的路由是from的时候才会重定向到to路由
<Switch>
<Redirect from='/old-path' to='/new-path'/>
<Route path='/new-path' component={Place}/>
</Switch>
Route
路由组件可能是React Router中了解和学习使用的最重要的组件。其最基本的责任是在位置与路线的路径匹配时呈现一些UI。
import { BrowserRouter as Router, Route } from 'react-router-dom'
//Home组件
const Home = (props)=>(<div>Home</div>)
//List组件
const List= (props)=>(<div>list</div>)
<Router>
<div>
<Route exact path="/" component={Home}/>
<Route path="/list" component={List}/>
</div>
</Router>
<Home/>
Route render methods
有3种方法可以使用呈现某些东西:
-
仅当位置匹配时才呈现的React组件.它将与route props一起呈现。
当您使用组件(而不是下面的渲染或子项)时,路由器使用React.createElement从给定组件创建一个新的React元素。 这意味着如果您向组件属性提供内联函数,则可以在每个渲染中创建一个新组件.这将导致现有组件卸载和新组件安装,而不是仅更新现有组件 当使用内联函数进行内联渲染时,请使用render或child(下文)
<Route path="/user/:username" component={User}/> const User = ({ match }) => { return <h1>Hello {match.params.username}!</h1> } -
Route render
这允许方便的在线呈现和包装,而不需要上述的不期望的重新安装。您可以使用组件支持为您创建一个新的React元素,而不必在位置匹配时传入要调用的函数。 渲染道具接收与组件渲染道具相同的所有route props。
警告:取决于,所以不要在同一个中使用两者
// 内联呈现 <Route path="/home" render={() => <div>Home</div>}/> // 包装/合成 //component:Component,取别名的意思 const FadingRoute = ({ component: Component, ...rest }) => ( <Route {...rest} render={props => ( <FadeIn> <Component {...props}/> </FadeIn> )}/> ) <FadingRoute path="/cool" component={Something}/> -
Route children
有时您需要渲染路径是否匹配该位置。在这些情况下,可以使用函数child prop。它的工作原理就像渲染,除了它被调用是否有匹配 children 渲染prop接收与组件和渲染方法相同的所有route props,除非路由未能匹配URL,则match为null。 这允许您根据路线是否匹配来动态调整用户界面。
例如我们做一个简单的路由转场动画
//Home组件
const Home: React.FC = (props) => {
return (
<div className="page">home</div>
)
}
//List组件
const List: React.FC = (props) => {
return (
<div className="page">list</div>
)
}
const WrapAnimation = ({ component: Component,...rest }) => {
console.log(rest.match)
return (
<CSSTransition
in={rest.match !== null}
classNames={{
enter: 'animated',
enterActive: 'fadeInLeft',
exit: 'animated',
exitActive: 'fadeOut'
}}
timeout={1000}
mountOnEnter={true}
unmountOnExit={true}
>
<div style={{position:'fixed',left:0,top:'30px',width:'100%'}}>
<Component {...rest} />
</div>
</CSSTransition>
)
}
<Router>
<div>
<Link to="/" >home</Link>
<Link to="/list">list</Link>
</div>
<Route path='/' exact children={(props) => {
return (
<WrapAnimation component={Home} {...props} />
)
}} />
<Route path='/list' children={(props) => {
return (
<WrapAnimation component={List} {...props} />
)
}} />
</Router>
警告:和优先级高于,所以不要在同一个中使用多个.
每个在不同的情况下都有用。您只能在给定的上使用这些方法之一。请看下面的解释,了解为什么你有3个选项。大多数时候你会使用component。
Route props
所有三个渲染方法将通过相同的三个route props
- match
- location
- history
withRouter
您可以通过withRouter高阶组件访问历史对象的属性和最接近的的匹配。随着路由每次路由改变时,路由器会重新渲染其组件,路径与<路径>渲染道具:{match,location,history}相同。
import { withRouter } from 'react-router'
//let NewComponent = withRouter(OldComponent)
const Test= withRouter((props)=>{
console.log(props,123)
return (
<div>123</div>
)
})
//普通组件也能拿到location,match,history等props