React Router官方文檔:https://reacttraining.com/react-router/web/guides/quick-start。
或許你不堪忍受閱讀英文文檔的痛苦可轉至印記中文:https://react-router.docschina.org/web/guides/quick-start。
閱讀以前您最好對React的基本語法有必定的瞭解。node
1.安裝nvmreact
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash 複製代碼
2.將下列代碼添加到~/.bashrc, ~/.profile, or ~/.zshrcgit
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
複製代碼
3.驗證是否安裝成功github
## 若是安裝成功,應輸出「nvm」, nvm 安裝完成後,可能要重啓一下終端纔有 nvm 這個命令。
command -v nvm
複製代碼
4.安裝Node(瞭解更多請參考nvm官網)web
#安裝node10.15.1版本
nvm install 10.15.1
複製代碼
yarn create react-app my-app 或者 npx create-react-app my-app
複製代碼
好的,一切都是那麼的順利!編程
這其實是很是好的,由於若是我想將代碼移植到react-native,我只需更新import語句就行了react-native
#src/app.js部分代碼
import { BrowserRouter as Router, Route } from "react-router-dom";
<Router basename="/calendar">
<div>
<Header />
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/topics" component={Topics} />
</div>
</Router>
複製代碼
#src/components/Header.js部分代碼
import { Link } from "react-router-dom";
const Header = () => (
<ul>
<li>
<Link to="/">Home</Link> #renders <a href="/calendar">
</li>
<li>
<Link to="/about">About</Link>> #renders <a href="/calendar/about">
</li>
<li>
<Link to="/topics">Topics</Link>> #renders <a href="/calendar/topics">
</li>
</ul>
);
複製代碼
關於他們的更多用法和區別能夠參考博客傳送門。數組
可經過路由傳遞參數給組件瀏覽器
接受一個字符串或者一個字符串數組ruby
# 第一種用法
<Route path="/users/:id" component={User} /> # id = props.match.params.id
or
# 第二種用法
const userRoutes = [
{
path: '/users/create',
component: UsersCreate
},
{
path: '/users/:id',
component: UsersShow
},
{
path: '/users/:id/edit',
component: UsersEdit
}
]
const UserRoutes = () => (
<Route
exact
path={['/users', ...userRoutes.map(route => route.path)]}
render={() => (
<section>
<UsersIndex />
<Switch>
{userRoutes.map(route => (
<Route key={route.path} exact path={route.path} component={route.component} />
))}
</Switch>
</section>
)}
/>
)
複製代碼
當exact=false時,若是訪問地址包含路由路徑,則匹配成功跳轉到當前路由,反之匹配不成功。
path | location.pathname | exact | matches |
---|---|---|---|
/one | /one | true | yes |
/one | /one/ | true | yes |
/one | /one/two | true | no |
/one | /one | false | yes |
/one | /one/ | false | yes |
/one | /one/two | false | yes |
當exact=true且strict=true,真實路徑===(徹底匹配)路由路徑,則匹配成功跳轉到當前路由,反之匹配不成功。能夠強制路徑結尾沒有反斜槓。
path | location.pathname | exact | matches |
---|---|---|---|
/one/ | /one | true | no |
/one/ | /one/ | true | yes |
/one/ | /one/two | true | yes |
# 須要注意的是:<Route component> 優先於 <Route render> 所以不要在同一個 <Route> 使用二者。
import FadeIn from "react-fade-in";
const FadingRoute = ({ component: Component, ...rest }) => {
return (
<Route {...rest} render={props => (
<FadeIn>
<Component {...props} />
</FadeIn>
)} />
)
};
const Animation = () => {
return (
<div>
Animation
</div>
);
};
class App extends Component {
render() {
return (
<div className="App">
<Router>
<div>
<Header />
<Switch>
<FadingRoute path="/animate" component={Animation} />
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/topics" component={Topics} />
<Route component={NotMatch} />
</Switch>
</div>
</Router>
</div>
)
}
}
const FadingRoute = ({ component: Component, ...rest }) => {
return (
<Route {...rest} render={props => (
<FadeIn>
<Component {...props} />
</FadeIn>
)} />
)
};
const Animation = () => {
return (
<div>
Animation
</div>
);
};
class App extends Component {
render() {
return (
<div className="App">
<Router>
<div>
<Header />
<Switch>
<FadingRoute path="/animate" component={Animation} />
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/topics" component={Topics} />
{/*<Route component={NotMatch} />*/}
</Switch>
</div>
</Router>
</div>
)
}
}
複製代碼
# 下面代碼相似於官方文檔 Custom Link例子
const MenuLink = ({ children, to, exact }) => {
return (
<Route path={to} exact={exact} children={({ match }) => {
return (
<NavLink activeStyle={match ? { color: "#ff00ff" } : {}} to={to}>
{match ? ">" : ""}{children}
</NavLink>
);
}} />
);
};
class App extends Component {
handleClick = () => {
console.log(this.props);
};
render() {
return (
<Router>
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<div className="App-intro">
<ul>
<li>
<MenuLink exact={true} to="/">
Home
</MenuLink>
</li>
<li>
<MenuLink exact={true} to="/about">
About
</MenuLink>
</li>
</ul>
<Switch>
<Route exact path="/" component={Home} />
<Route strict exact path="/about" component={About} />
<Route component={NoMatch} />
</Switch>
</div>
</div>
</Router>
);
}
}
複製代碼
Link的表現形式相似於a標籤,可是功能更強大。
import { Link } from 'react-router-dom'
## 聲明式
<Link to="/about" className='active'>About</Link>
## 編程式
props.history.push("/about");
<Link to='/courses?sort=name'/>
<Link to={{
pathname: '/courses',
search: '?sort=name',
hash: '#the-hash',
state: { fromDashboard: true }
}}/>
#掛載好的Link能夠對其進行DOM操做
const refCallback = node => {
node.getAttribute("href"); # /
}
<Link to="/" innerRef={refCallback} />
複製代碼
給匹配到的路由添加樣式,是一種特殊的Link,在用法上大體相同
import { NavLink } from 'react-router-dom <NavLink to="/faq"activeClassName="selected"> NavLink </NavLink> <NavLink to="/faq" activeStyle={{ fontWeight: 'bold',color: 'red' }}> NavLink </NavLink> 複製代碼
有時爲了肯定連接是否處於活動狀態而添加額外邏輯
import queryString from "query-string";
const getQuery = (match, location) => {
if (!match) {
return false
}
const query = queryString.parse(location.search).job;
return query;
};
<NavLink to="/faq?job=FE"
activeClassName="selected"
isActive={ getQuery }> NavLink </NavLink>
複製代碼
Switch用來包裹Route,它裏面不能放其餘元素。結合如下代碼舉個栗子:用戶輸入一個URL是'/about',假設沒有Switch存在,那麼根據前面所提到的路由匹配規則About、Users、NotMatch都將被渲染。因爲Switch從上至下匹配Route,查找到
<Route path="/about" component={About}>
時中止搜索並只會渲染About組件。
import { Link, Switch, Route } from 'react-router-dom'
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/:id" component={Users} />
<Route component={NotMatch} />
</Switch>
複製代碼
Wrapper組件一開始並無註冊路由,不會有路由屬性的傳遞(match、location和history)。可是能夠經過WithRouter高階組件訪問 history對象的屬性和最近的 的 match,當路由渲染時,withRouter會將已經更新的 match、location和history 屬性傳遞給被包裹的組件。
# src/components/Home.js部分代碼
import React from "react";
import { withRouter } from "react-router";
const Wrapper = ({ history }) => {
return (
<div>
<button onClick={() => history.push("/about")}>Hello</button>
</div>
);
};
const WithRouterWrapper = withRouter(Wrapper);
const Home = (props) => {
return (
<div>
<h1>Home</h1>
<button onClick={() => {
props.history.push("/about");
}}>前往about頁面
</button>
<WithRouterWrapper />
</div>
);
};
export default Home;
複製代碼