路由的基礎用法回顧, 源碼study,文章首發於 docs,求個star
路由依賴於 react-router
,可是通常 pc 路由使用 react-router-dom
,它依賴於 react-router
javascript
npm i react-router-dom -S
a
標籤hash
路由,BrowserRouter 是 history
路由import { HashRouter, Route, Link } from 'react-router-dom' class App extends Component { ... render() { return ( <div> <Link to="/" >首頁</Link> <Link to="/page">Page</Link> {/* 配置路由規則 exact表示精確匹配,防止匹配其餘頁面的時候匹配到/,也就是首頁*/} <Route path="/" exact component={Home}></Route> <Route path="/page" component={Page}></Route> <Route path={`/user/login`} render={routeProps => { return ( <List name="這是render渲染" user="mondo" {...routeProps} /> ); }} ></Route> </div> ); } } ReactDOM.render( <HashRouter> <App/> </HashRouter>, document.getElementById('root') )
Link
只配置路由,NavLink
可作導航路由,可配置activeClassName
和 activeStyle
import { NavLink as Link } from 'react-router-dom'; class Nav extends Component { render () { return ( <ul className="nav"> <li className="list"><NavLink to="/archive" activeClassName='active'>歸檔</NavLink></li> <li className="list"><NavLink to="/about" activeClassName='active'>關於</NavLink></li> </ul> ); }; } export default Nav;
在想要嵌套的組件裏再次配置路由java
// User.js import React from 'react' import { Route, Link } from 'react-router-dom' const User = (props) => { // match 能夠讀取上層路由 const { match } = props return ( <div> <Link to={`${match.path}/login`}>登陸</Link> <Link to="/user/reg">註冊</Link> <Route path={`${match.path}/login`}>login</Route> <Route path="/user/reg">reg</Route> </div> ) } export default User // App.js <Route path="/user" component={User}></Route>
props.match.params
訪問// App.js <Link to="/list/1/4">列表</Link> {/* 必須使用 component 來指定組件,否則訪問不到match */} <Route path="/list/:id/:user" component={List}/> // List.js const List = (props) => { console.log(props.match.params) // { id: 1, user: 4 } return ( <h2> { props.name }{ props.children } </h2> ) }
?
後面的值,可是 router
沒提供相應的方法,須要本身寫一個函數來提取參數to
傳遞對象 state利用 props.history
來跳轉路由react
// List.js const { history } = props const goRoute = () => { if (history) { history..push('/user') } } // 能夠使用對象傳值 const goRoute = () => { if (history) { history..push({ pathname: '/user', state: { id: 2 } }) } }
重定向使用 Switch
組件git
// ErrorPage.js import React from 'react' class Error extends React.Component{ render(){ return( <h1>頁面404</h1> ) } } export default Error // App.js import ErrorPage from './components/ErrorPage' class App extends React.Component { ... render() { ... {/* Switch表示若是匹配到了路由,就再也不往下面匹配了,若是不寫Switch,則一直會匹配到404頁面 */} <Switch> {/* 配置路由規則 exact表示精確匹配,防止匹配其餘頁面的時候匹配到/,也就是首頁*/} <Route path="/home" exact>Home</Route> <Route path="/page" component={Page}></Route> <Route path="/user" component={User}></Route> {/* 必須使用 component 來指定組件,否則訪問不到match */} <Route path="/list/:id/:user" component={List}></Route> <Redirect from="/" to="/home" exact></Redirect> {/* 沒有寫path表示匹配到全部的路徑 */} <Route component={ErrorPage} /> </Switch> } }
因爲只有 Route
包裹的組件才能夠訪問到 props
內部的路由信息,能夠引入 withRouter
高階組件來使內部組件也能夠訪問路由信息github
import React from 'react' import { withRouter } from 'react-router-dom' const GoBack = props => { console.log(props) const goBack = () => { props.history.go(-1) } return <button onClick={goBack}>返回</button> } export default withRouter(GoBack)