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;
复制代码