reactrouterdom 的使用

index.tsx

import React from 'react';
import {
  BrowserRouter,
  HashRouter,
  Route,
  Link,
  NavLink,
  Switch,
  Redirect,
} from 'react-router-dom';
import Header from './Comps/Header';
import MyNavLink from './Comps/MyNavLink';
import './index.css';
import About from './About';
import Home from './Home';
import News from './News';
const RouterDome: React.FC = () => {
  /*
   * react-router-dom 的使用,当前版本 5.3.0
   *
   * BrowserRouter 历史模式路由, HashRouter hash模式路由
   * 使用时 Route 时必须要用 BrowserRouter 或 HashRouter 包裹,而且只能有一个,可以直接包裹在App上。
   *
   * NavLink 和 Link 的区别
   * NavLink 可以设置 activeClassName 属性,当该属性与当前路径匹配时,会自动将属性内的类名添加到元素上
   * <NavLink activeClassName="active" className="route-li" to="/about">
   *
   * Switch 的 作用
   * 可以提高路由匹配的效率
   * 当多个 Route 存在相同的 path 时,那么这几个组件将会同时显示
   * 如下:(Home 组件 和 About 组件 将同时显示)
   * <Route path="/home" component={Home}></Route>
   * <Route path="/home" component={About}></Route>
   * 若 使用 Switch 将 Route 包裹,那么当路由匹配当第一个组件时,将不再往下配置,则只会显示 Home 组件
   *
   * router 的 模糊匹配(默认模式)和 严格匹配
   *
   * 模糊匹配(匹配顺序是从左往右进行的)
   * 例子1 (匹配成功)
   * <NavLink to="/home/a/b/c">News</NavLink>
   * <Route path="/home" component={Home}></Route>
   *
   * 例子2 (匹配失败)
   * <NavLink to="/a/home/c">News</NavLink>
   * <Route path="/home" component={Home}></Route>
   *
   * 严格模式
   * 开启严格匹配模式,在 Route 组件内 添加 exact 即可, 且 to 和 path 必须相同才能匹配成功
   * 如:
   *  <NavLink to="/about">News</NavLink>
   *  <Route exact path="/about" component={About}></Route>
   * 需注意一般情况下,不要开启严格匹配模式,可能会导致二级路由匹配失败
   *
   * Redirect 路由重定向
   * 用法 <Redirect to="/home"></Redirect>,在 to 中指定需要展示的组件
   * 当所有点路由都匹配不上时,该组件才会生效
   *
   * 嵌套路由
   * 子级路由必须以父级路由名称为开头,而且父级路由不能开启 exact 模式
   * 如:
   *  父级
   *  <Route path="/news" component={News}></Route>
   *  子级
   *  <Route path="/news/compA" component={CompA}></Route>
   *  <Route path="/news/compB" component={CompB}></Route>
   *
   * router params 参数
   * 传参:<NavLink to="/news/compA/a">compA</NavLink>
   * 接收:<Route path="/news/compA/:type" component={CompA}></Route>
   * 获取参数:通过 props.match.params 即可拿到 type = a
   *
   * router search 参数
   * 传参:<NavLink to="/news/compB?name=compB&type=B">compB</NavLink>;参数通过 ? 拼接在路径上,多个参数用 & 隔开,且无需去接收
   * 获取参数:通过 props.location.search 获取,需注意这里获取到的参数是字符串 ?name=compB&type=B
   * 示例:
   *  import React from 'react';
   *  import qs from 'querystring'; // 无需安装,此为自带的库
   *
   *  interface ICompB {
   *    [propName: string]: any;
   *  }
   *  const CompB: React.FC<ICompB> = (props) => {
   *    const { search } = props.location;
   *    const query = qs.parse(search.slice(1));
   *    console.log(query); // { name: 'compB', type: 'B' }
   *    return <h3>this is CompB</h3>;
   *  };
   *  export default CompB;
   *
   * router state 参数
   * 注意:HashRouter 模式下,刷新会导致 state 数据丢失,因此 HashRouter 模式下不推荐使用该方法传参
   * 示例:
   *  传参:<NavLink to={{ pathname: '/news/compC', state: { name: 'compC', type: 'C' } }}>compC</NavLink>
   *  获取参数:
   *  import React from 'react';
   *  const CompC: React.FC = (props) => {
   *    console.log((props as any).location.state); // {name: 'compC', type: 'C'}
   *    return <h3>this is CompC</h3>;
   *  };
   *  export default CompC;
   *
   * router push 和 replace
   * push(默认模式),会在浏览器上留下记录
   * replace 则是替换当前路径,且不会在浏览器留下记录
   * 开启replace模式:
   * 如:<NavLink replace to="/news/compA/a">compA</NavLink>,<Link replace></Link>
   *
   * 编程式路由的使用
   * 先熟悉下 props.history 几个常用的属性
   * history: {
   *  go: ƒ go(n),
   *  goBack: ƒ goBack(),
   *  goForward: ƒ goForward(),
   *  push: ƒ push(path, state),
   *  replace: ƒ replace(path, state)
   * }
   * go 的使用
   * n 为正数则往后退,负数则往前退
   * 示例:(props as any).history.go(n);
   *
   * goBack 的使用
   * 往前退一步
   * 示例:(props as any).history.goBack();
   *
   * goForward 的使用
   * 往后退一步
   * 示例:(props as any).history.goForward();
   *
   * push 的使用
   * 第一种情况,params 参数
   * 示例:(props as any).history.push('/news/compA/a');
   * 第二种情况,search 参数
   * 示例:(props as any).history.push('/news/compB?name=compB&type=B');
   * 第三种情况,state 参数
   * 示例:(props as any).history.push('/news/compC', { name: 'compC', type: 'C' });
   *
   * replace 和 push 使用基本相同,只不过是 把 push 替换成了 replace,参考上面案例。
   * 需注意以上的路由方法只能在路由组件中使用
   *
   * withRouter
   * 作用:使一般组件也能像路由组件一样,调用 history 身上的方法
   */
  return (
    <BrowserRouter>
      <div className="router-demo">
        {/* 一般组件 */}
        <Header></Header>
        <div className="router-main">
          <div className="left">
            <ul>
              {/* <Link to="./home" className="route-li">Home</Link> */}
              <li>
                <NavLink activeClassName="active active2" className="route-li" to="/home">
                  Home
                </NavLink>
              </li>
              <li>
                <NavLink activeClassName="active" className="route-li" to="/about">
                  About
                </NavLink>
              </li>
              <li>
                <MyNavLink to="/news">News</MyNavLink>
              </li>
            </ul>
          </div>
          <div className="right">
            <Switch>
              {/* <Route path="/home" component={Home}></Route> */}
              <Route path="/home" component={Home}></Route>
              <Route path="/about" component={About}></Route>
              <Route path="/news" component={News}></Route>
              <Redirect to="/home"></Redirect>
            </Switch>
          </div>
        </div>
      </div>
    </BrowserRouter>
  );
};

export default RouterDome;
News 组件
import React from 'react';
import { NavLink, Switch, Route, Redirect } from 'react-router-dom';
import CompA from './CompA';
import CompB from './CompB';
import CompC from './CompC';
import './index.css';
const News: React.FC = (props) => {
  function onGo(n: number) {
    // n 为正数则往后退,负数则往前退
    (props as any).history.go(n);
  }
  function goBack() {
    // 往前退一步
    (props as any).history.goBack();
  }
  function goForward() {
    // 往后退一步
    (props as any).history.goForward();
  }
  function onPushParams() {
    (props as any).history.push('/news/compA/a');
  }
  function onPushSearch() {
    (props as any).history.push('/news/compB?name=compB&type=B');
  }
  function onPushState() {
    (props as any).history.push('/news/compC', { name: 'compC', type: 'C' });
  }
  return (
    <div className="news-content">
      <h2>this is News</h2>
      <button onClick={() => onGo(-1)}>go -1</button>
      <button onClick={() => onGo(1)}>go 1</button>
      <button onClick={() => goBack()}>goBack 往前退一步</button>
      <button onClick={() => goForward()}>goForward 往后退一步</button>
      <button onClick={() => onPushParams()}>push params 传参</button>
      <button onClick={() => onPushSearch()}>push search 传参</button>
      <button onClick={() => onPushState()}>push state 传参</button>

      <ul>
        <li>
          <NavLink to="/news/compA/a">compA</NavLink>
        </li>
        <li>
          <NavLink to="/news/compB?name=compB&type=B">compB</NavLink>
        </li>
        <li>
          <NavLink to={{ pathname: '/news/compC', state: { name: 'compC', type: 'C' } }}>
            compC
          </NavLink>
        </li>
      </ul>
      <Switch>
        <Route path="/news/compA/:type" component={CompA}></Route>
        <Route path="/news/compB" component={CompB}></Route>
        <Route path="/news/compC" component={CompC}></Route>
        <Redirect to="/news/compA/a"></Redirect>
      </Switch>
    </div>
  );
};

export default News;
Header 组件
import React from 'react';
import { withRouter } from 'react-router-dom';

const Header: React.FC = (props) => {
  function onGo(n: number) {
    // n 为正数则往后退,负数则往前退
    (props as any).history.go(n);
  }
  return (
    <>
      <h2>React Router Dome</h2>
      <button onClick={() => onGo(-1)}>go -1</button>
      <button onClick={() => onGo(1)}>go 1</button>
    </>
  );
};

export default withRouter(Header);
原文地址:https://www.cnblogs.com/fczbk/p/15724681.html