react-router-dom

1概念

单页应用:初始化时加载相应的资源(html/css/js)。不刷新,通过js实现界面局部刷新。

  

1.1 分类

前端路由:path-component,根据path显示对应的路由页面。

后端路由:path-function,根据path处理请求,返回响应。

1.2 路由原理

借助于BOM中的history,栈结构,默认为push。

push:压栈,出栈

repace:替换栈顶记录

2基本使用

2.1 v5.3.3

路由组件(Home):this.props={history/location/match}

一般组件(Header):this.props={ }

import { withRouter } from 'react-router-dom'

// 一般组件没有history属性等,用withRouter函数解决,返回值是一个新组件
export default withRouter(Header)

    console.log(this.props.location.pathname)//地址栏路由
    console.log(this.props.match.path)
    console.log(this.props.match.url)

e95ac8e4c2a848c05bcdde6213ac2bb0.png

index.js

BrowserRouter:使用H5的history;兼容性差一点;刷新后state参数还在;用的多

HashRouter:url#后的内容不会发给服务器,兼容性好一点;刷新后state参数不在;解决路径错误问题

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
// HashRouter带# 
import { BrowserRouter } from 'react-router-dom';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
);

App.jsx

import { Route, Link, NavLink, Switch, Redirect } from 'react-router-dom'

export default class App extends Component {
  render () {
    return (
      <div>
        <div className="row">
          <div className="col-xs-offset-2 col-xs-8">
            <Header />
          </div>
        </div>
        <div className="row">
          {/* --------导航区-------- */}
          <div className="col-xs-2 col-xs-offset-2">
            <div className="list-group">
              {/* 1.原生html中,靠<a>跳转不同的页面 */}
              {/* <a className="list-group-item" href="./about.html">About</a> */}

              {/* 2.在React中靠路由链接实现切换组件--编写路由链接 */}
              {/*a. 测试模糊匹配(默认) */}
              <Link className="list-group-item" to="/about/a/b">About</Link>
              {/*b. NavLink点击追加高亮类名 */}
              {/* <NavLink activeClassName="demo" className="list-group-item" to="/home">Home</NavLink> */}
              {/*c.封装NavLink,标签体内容Home为children属性;默认为push */}
              <MyLink to="/home">Home</MyLink>
              {/*d.问题:to改为二级路由后刷新:找不到bootstrap文件 ;改为绝对路径:public(React)或者/(常用)*/}
              <MyLink to="/test/demo">测试样式丢失</MyLink>
            </div>
          </div>
          {/* --------展示区-------- */}
          <div className="col-xs-6">
            <div className="panel">
              <div className="panel-body">
                {/* 注册路由:<Switch>组件匹配成功后,不再匹配其他组件。包裹路由组件,提高路由匹配效率 */}
                <Switch>
                  {/* exact开启精准匹配,需要再开启。 */}
                  <Route path="/about" component={About} exact />
                  <Route path="/home" component={Home} />
                  <Route path="/home" component={Test} />
                  <Route path="/test/demo" component={Test} />
                  {/* 匹配不到显示,放到最下面 */}
                  <Redirect to="/about" />
                </Switch>
              </div>
            </div>
          </div>
        </div>
      </div>
    )
  }
}

2.2 v6.3.0

App.jsx

import { NavLink, Routes, Route, Navigate, useRoutes } from 'react-router-dom'
import routes from './routes'
export default function App () {
  function computedClassName ({ isActive }) {
    return isActive ? 'list-group-item atguigu' : 'list-group-item'
  }
  //根据路由表生成对应的路由规则
  const element = useRoutes(routes)
  return (
    <div>
      <div className="row">
        <Header />
      </div>
      <div className="row">
        <div className="col-xs-2 col-xs-offset-2">
          <div className="list-group">
            {/* 路由链接:className={()=>{}}函数值可以全局定义实现复用*/}
            <NavLink className={computedClassName} to="/about">About</NavLink>
            {/* navLInk的end属性会去掉父级高亮 */}
            <NavLink className={computedClassName} to="/home" end>Home</NavLink>
          </div>
        </div>
        <div className="col-xs-6">
          <div className="panel">
            <div className="panel-body">
              {/* 1.注册路由:Routes包裹Route:path-element ;caseSensitive是否区分大小写 */}
              {/* <Routes>
                <Route path="/About" caseSensitive={false} element={<About />} />
                <Route path="/home" element={<Home />} />
                {/* navigate渲染引起视图切换,包含replace属性 */}
                <Route path="/" element={<Navigate to="/about" />} />
              </Routes> */}

              {/* 2.路由表 */}
              {element}
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}

routes/index.js

import { Navigate } from 'react-router-dom'
const arr=[
  {
    path: '/about',
    element:<About/>
  },
  {
    path: '/home',
    element: <Home />,
    children: [//二级路由
      {
        path: 'news',
        element:<News/>
      },
      {
        path: 'message',
        element: <Message />,
        children: [
          //params参数
          // {
          //   path: 'detail/:id/:title/:content',
          //   element:<Detail/>
          // },
          //search参数
          // {
          //   path: 'detail',
          //   element:<Detail/>
          // },
          //state参数
          {
            path: 'detail',
            element:<Detail/>
          },
        ]
      }
    ]
  },
  {
    path: '/',
    element:<Navigate to="/about"/>
  },
]
export default arr;

3 嵌套路由

3.1 v5.3.3

      <div>
        <h3>我是Home的内容</h3>
        {/* 二级路由页面 */}
        <div>
          <ul className="nav nav-tabs">
            <li>
              {/* home组件匹配到了; /home/news组件匹配到了 。 */}
              <MyNavLink to="/home/news">News</MyNavLink>
            </li>
            <li>
              <MyNavLink to="/home/message">Message</MyNavLink>
            </li>
          </ul>
          <Switch>
            <Route path="/home/news" component={News} />
            <Route path="/home/message" component={Message} />
            <Redirect to="/home/news" />
          </Switch>
        </div>
      </div>

3.2 v6.3.0

    import { Outlet, NavLink } from 'react-router-dom'
    <div>
      <ul className="nav nav-tabs">
        <li>
          <NavLink className="list-group-item" to="news" >News</NavLink>
        </li>
        <li>
          <NavLink className="list-group-item" to="message">Message</NavLink>
        </li>
      </ul>
      {/* 指定路由组件呈现的位置 */}
      <Outlet />
    </div>

4 路由传参

刷新后参数不丢,清缓存丢。

携带参数方式:query;params;body(json/urlencoded)

03daaa22c9f219c0abf68e926ab04131.png

4.1 v5.3.3

4.1.1 params参数

//路由链接
<Link to={`/home/message/detail/${item.id}/${item.title}`}>{item.title}</Link>

//注册路由
<Route path="/home/message/detail/:id/:title" component={Detail} />

//接收
const { id, title } = this.props.match.params

4.1.2 search参数

import qs from 'querystring'

<Link to={`/home/message/detail/?id=${item.id}&title=${item.title}`}>{item.title}</Link>

<Route path="/home/message/detail" component={Detail} />

//接收
const { search } = this.props.location
console.log(search, 'search参数')//?id=1&title=消息1
const { id, title } = qs.parse(search.slice(1))

//扩展
let obj = { name: 'tom', age: 18 }
console.log(qs.stringify(obj))//name=tom&age=18
let str = 'name=ming&age=19'
console.log(qs.parse(str))//{name: 'ming', age: '19'}

4.1.3 state参数

<Link to={{ pathname: '/home/message/detail', state: { id: item.id, title: item.title } }}>{item.title}</Link>

<Route path="/home/message/detail" component={Detail} />

//接收
const { id, title } = this.props.location.state || {}

4.2 v6.3.0

4.2.1 params参数

import { useParams, useMatch } from 'react-router-dom'

<Link to={`detail/${item.id}/${item.title}/${item.content}`}>{item.title}</Link>

// 方式一:
const { id, title, content } = useParams()
// 方式二:
const x = useMatch('/home/message/detail/:id/:title/:content')
console.log(x.params);//{id: '2', title: '消息2', content: '2222内容'}

4.2.2 search参数

import { useSearchParams, useLocation} from 'react-router-dom'

<Link to={`detail?id=${item.id}&title=${item.title}&content=${item.content}`}>{item.title}</Link>

// 方式一:
const [search, setSearch] = useSearchParams();
const id = search.get('id');
const title = search.get('title');
const content = search.get('content');
{/* <button onClick={() => { setSearch('id=0&title=haha&content=xixi') }}>更新search参数</button> */}
// 方式二:
const x = useLocation()
console.log(x.search)//?id=1&title=%E6%B6%88%E6%81%AF1&content=1111%E5%86%85%E5%AE%B9

4.2.3 state参数

import { useLocation } from 'react-router-dom'

<Link to="detail" state={{ id: item.id, title: item.title, content: item.content }}>{item.title}</Link>

// 方式一:
const { state: { id, title, content } } = useLocation()

5 编程式导航

5.1 v5.3.3

//push跳转+携带params参数
this.props.history.push(`/home/message/detail/${id}/${title}`)
//push跳转+携带search参数
this.props.history.push(`/home/message/detail?id=${id}&title=${title}`)
//push跳转+携带state参数
this.props.history.push(`/home/message/detail/`, { id, title })

this.props.history.replace(`/home/message/detail/`, { id, title })

this.props.history.goBack()

this.props.history.goForward()

this.props.history.go(-1)

5.2 v6.3.0

import { useNavigate } from 'react-router-dom'

const navigate = useNavigate()
navigate(`detail/${item.id}/${item.title}/${item.content}`, {
    replace: false,
})

navigate(`detail?id=${item.id}&title=${item.title}&content=${item.content}`, {
    replace: false,
})

navigate('detail', {
    replace: false,
    state: {
        id: item.id, title: item.title, content: item.content
    }
})

navigate(-1)

navigate(1)

6 其他钩子

import { useNavigationType, useResolvedPath,useInRouterContext,useOutlet } from 'react-router-dom'

// push/replace/pop(怎么来的当前页面?刷新!)
console.log(useNavigationType())

// 给定一个 URL值,解析其中的:path、search、hash值。
console.log(useResolvedPath('/user?id=001&name=tom#qwe'))//{pathname: '/user', search: '?id=001&name=tom', hash: '#qwe'}

//被BrowserRouter包裹返回true
const navigate = useInRouterContext()
console.log(navigate)

// 返回什么???
console.log(useOutlet(), 'useOutlet')

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值