React Router文档阅读笔记(上)

React Router官方文档:https://reacttraining.com/react-router/web/guides/quick-start。
或许你不堪忍受阅读英文文档的痛苦可转至印记中文:https://react-router.docschina.org/web/guides/quick-start。
阅读以前您最好对React的基本语法有必定的了解。node


准备工做

安装nod环境:

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

官方推荐使用create-react-app建立项目

yarn create react-app my-app 或者 npx create-react-app my-app
复制代码

好的,一切都是那么的顺利!编程

BrowserRouter 和 HashRouter

  • react-router-dom将在浏览器中使用
  • react-router-native用于react-native app

这其实是很是好的,由于若是我想将代码移植到react-native,我只需更新import语句就行了react-native

  • 在React Router 4.0中Router已经被移除了,取而代之的是BrowserRouter和HashRouter。他们一般出如今路由的最外层。
#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>
);
复制代码

关于他们的更多用法和区别能够参考博客传送门数组

Route

  1. path:string | string[]

可经过路由传递参数给组件浏览器

接受一个字符串或者一个字符串数组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>
    )}
  />
)
复制代码
  1. exact: bool ( 精确匹配 )

当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
  1. strict:bool ( 严格匹配 )

当exact=true且strict=true,真实路径===(彻底匹配)路由路径,则匹配成功跳转到当前路由,反之匹配不成功。能够强制路径结尾没有反斜杠。

path location.pathname exact matches
/one/ /one true no
/one/ /one/ true yes
/one/ /one/two true yes
  1. render:fun
# 须要注意的是:<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>
        )
    }
}
复制代码
  1. children: func
# 下面代码相似于官方文档 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

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

NavLink

给匹配到的路由添加样式,是一种特殊的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

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

WithRouter

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;

复制代码
相关文章
相关标签/搜索