React学习31(react-router-dom 6.x版本的使用)

总述:因为在2021年11月推出了react-router-dom@6的版本,包括现在使用react脚手架创建项

目时, react-router-dom默认是6的版本, 以下将具体说明两个版本之间的不同的使用功能

如若需要了解react-router-dom@5版本相关的写法,可参考个人博客前期的文章,希望对你有所帮

概述

1、react-router以三个不同的包发布到npm上,他们分别为

        1)react-router:路由的核心库,提供了很多的组件,钩子

        2)react-router-dom:包含react-router所有内容,并添加了一些专门用于DOM的组件,例如

<BrowserRouter>等

        3)react-router-native:包含react-router所有内容,并添加一些专门用于ReactNative的API,

例如<NativeRouter>等

2、与React Router5版本相比,改变了什么?

        1)内置组件的变化:移除了<Switch/>,新增<Routes/>等

        2)语法的变化:component={About}变为element={<About/>}等

        3)新增了多个hook:useParams, useNavigate, useMatch等

        4)官方明确推荐函数式组件了

Component内置组件

<BrowserRouter/>

作用:用于包裹整个应用

代码示例:

import React from 'react'
import { createRoot } from 'react-dom/client';//更新后的写法
import { BrowserRouter } from 'react-router-dom';

// react17版本写法
// import ReactDOM from 'react-dom'

import App from './App.jsx'

// react17版本写法
// ReactDOM.render(<App/>, document.getElementById('root'))

// react18版本写法
createRoot(document.getElementById('root')).render(
  <BrowserRouter>
    <App/>
  </BrowserRouter>

);

<HashRouter/>

说明:作用与BrowserRouter一样,但HashRouter修改的是地址的hash值

备注:6.X版本中HashRouter、BrowserRouter的用法与5.x相同

<Routes/>与<Route/>

1)6.x版本中移除了先前的Swith,引入了新的替代者Routes

2)Routes和route要配合使用,且必须要用Routes包裹Route

3)Route相当于一个if语句,如果其路径与当前URL匹配,则呈现其对应的组件

4)Route的caseSensitive属性用于指定:匹配时是否区分大小写(默认为false)

5)当URL发生变化时,Routes都会查看所有子Route元素以找打最佳匹配并呈现组件

6)Route也可以嵌套使用,且可配合useRoutes()配置路由表,但需要通过Outlet组件来渲染其子

组件

<Link/>

作用:修改URL,且不发送网络请求(路由链接)

注意:外侧需要用BrowserRouter或HashRouter包裹

示例代码:

import React from 'react'
import { Link } from 'react-router-dom'

export default function Test() {
  return (
    <div>
      <Link to='/路径'>按钮</Link>
    </div>
  )
}

<NavLink/>

作用:与Link组件类似,且可实现导航的高亮效果<

import { NavLink } from "react-router-dom";

// 注意:NavLink默认类名是active,下面是自定义的class
<NavLink
  to='login'
  className={({isActive}) => {
    console.log('home', isActve);
    return isActive ? 'base one' : 'base'
  }}
>login</NavLink>

// 默认情况下,当Home的子组件匹配成功后,Home的导航也会亮
// 当NavLink添加end属性后,若Home的子组件匹配成功,则Home的导航没有高亮效果
{/* <NavLink to='home' end></NavLink> */}

<Navigate/>

作用:只要Navigate组件被渲染,就会修改路径,切换视图

replace属性用于控制跳转模式(push或者是replace,模式是push)

示例代码:

import React, {useState} from 'react'
import { Navigate } from 'react-router-dom';

export default function Home() {
  const [sum, setSum] = useState(1)
  console.log(useState(1));
  return (
    <div>
      <h3>我是Home组件</h3>
      {sum === 2 ? <Navigate to='/about'/> : <h4>当前sum的值是:{sum}</h4>}
      <button onClick={() => setSum(2)}>点我将sum变为2</button>
    </div>
  )
}

<Outlet/>

当Route产生嵌套时,渲染其对应的后续子路由

示例:

import About from "../pages/About"
import Home from "../pages/Home"
import News from "../pages/News"
import Message from "../pages/Message"
import { Navigate } from "react-router-dom"

export default [
    {
      path:'/about',
      element:<About/>
    },
    {
      path:'/home',
      element:<Home/>,
      children:[
        {
          path:'news',
          element:<News/>
        },
        {
          path:'message',
          element:<Message/>
        }
      ]
    },
    {
      path:'/',
      element:<Navigate to='/about'/>
    }
  ]

// Home.jsx
import React from 'react'
import { NavLink, Outlet } from 'react-router-dom'

export default function Home() {
  return (
    <div>
      <h3>我是Home组件</h3>
      <div>
        <ul className='nav nav-item'>
          <li>
            {/* to的写法一,在父级路径下在写子级路径 */}
            {/* <NavLink className='list-group-item' to="/home/news">News</NavLink> */}
            {/* to的写法二 */}
            <NavLink className='list-group-item' to="news">News</NavLink>
          </li>
          <li>
            <NavLink className='list-group-item' to="/home/message">Message</NavLink>
          </li>
        </ul>
        {/* 指定路由组件呈现的位置 */}
        <Outlet/>
      </div>
    </div>
  )
}

Hooks

useRoutes()

作用:根据路由表,动态创建Routes和Route

示例代码:

routes-index.js

import About from "../pages/About"
import Home from "../pages/Home"
import { Navigate } from "react-router-dom"

export default [
    {
      path:'/about',
      element:<About/>
    },
    {
      path:'/home',
      element:<Home/>
    },
    {
      path:'/',
      element:<Navigate to='/about'/>
    }
  ]

App.jsx

import React from 'react'
import {NavLink, useRoutes} from 'react-router-dom'
import routes from './routes/index'

export default function App() {
  // 根据路由表生成对应的路由规则
  const element = useRoutes(routes)
  return (
    <div>
      <div className="row">
          <div className="col-xs-offset-2 col-xs-8">
            <div className="page-header"><h2>Vue Router Demo</h2></div>
          </div>
        </div>
        <div className="row">
          <div className="col-xs-2 col-xs-offset-2">
            <div className="list-group">

              {/* 在React中靠路由链接切换组件 */}
                <NavLink className="list-group-item" to="/about">About</NavLink>
                <NavLink className="list-group-item" to="/home">Home</NavLink>
            </div>
          </div>
          <div className="col-xs-6">
            <div className="panel">
              <div className="panel-body">
              {/* 注册路由 */}
              {/* <Routes>
                <Route path= "/about" element={<About/>}/>
                <Route path="/home" element={<Home/>}/>
                <Route path='/' element={<Navigate to='/about'/>}/>
              </Routes> */}
              {element}
              </div>
            </div>
          </div>
        </div>
    </div>
  )
}

useNavigate()

作用:返回一个函数用来实现编程式导航

示例代码:

Message.jsx

import React, {useState} from 'react'
import { Link, Outlet, useNavigate } from 'react-router-dom'

export default function Message() {
  const [message] = useState([
    {id:'001', title:'消息001', content:'锄禾日当午'},
    {id:'002', title:'消息002', content:'汗滴禾下土'},
    {id:'003', title:'消息003', content:'谁知盘中餐'},
    {id:'004', title:'消息004', content:'粒粒皆辛苦'}
  ])
  const navigate = useNavigate()
  function showDeatil(m) {
    navigate('detail', {
      replace:false,
      state:{
        id:m.id,
        title:m.title,
        content:m.content
      }
    })
  }
  return (
    <div>
      <ul>  
        {
          message.map((m) => {
            return <li key={m.id}>
                      <Link to='detail'
                        state={{
                          id:m.id,
                          title:m.title,
                          content:m.content
                        }}
                      >{m.title}</Link>&nbsp;
                      <button onClick={() =>showDeatil(m)}>查看详情</button>
                    </li>
          })
        }
       
      </ul>
      <hr/>
      <Outlet/>
    </div>
  )
}

Header.jsx

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

export default function Header() {
  const navigate = useNavigate()
  function forward() {
    navigate(1)
  }
  function back() {
    navigate(-1)
  }
  return (
    <div>
      <div className="col-xs-offset-2 col-xs-8">
       <div className="page-header"><h2>Vue Router Demo</h2></div>
      </div>
      <button onClick={forward}>前进</button>
      <button onClick={back}>后退</button>
    </div>
  )
}

useParams()

作用:当前匹配路由的params参数,类似5中的match.param

代码示例:

Message.jsx

import React, {useState} from 'react'
import { Link, Outlet } from 'react-router-dom'

export default function Message() {
  const [message] = useState([
    {id:'001', title:'消息001', content:'锄禾日当午'},
    {id:'002', title:'消息002', content:'汗滴禾下土'},
    {id:'003', title:'消息003', content:'谁知盘中餐'},
    {id:'004', title:'消息004', content:'粒粒皆辛苦'}
  ])
  return (
    <div>
      <ul>  
        {
          message.map((m) => {
            return <li key={m.id}>
                      <Link to={`detail/${m.id}/${m.title}/${m.content}`}>{m.title}</Link>&nbsp;
                    </li>
          })
        }
       
      </ul>
      <hr/>
      <Outlet/>
    </div>
  )
}

routes-index,js

import About from "../pages/About"
import Home from "../pages/Home"
import News from "../pages/News"
import Message from "../pages/Message"
import Detail from "../pages/Detail"
import { Navigate } from "react-router-dom"

export default [
    {
      path:'/about',
      element:<About/>
    },
    {
      path:'/home',
      element:<Home/>,
      children:[
        {
          path:'news',
          element:<News/>
        },
        {
          path:'message',
          element:<Message/>,
          children:[
            {
              path:'detail/:id/:title/:content',
              element:<Detail/>
            }
          ]
        }
      ]
    },
    {
      path:'/',
      element:<Navigate to='/about'/>
    }
  ]

Detail.jsx

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

export default function Detail() {
  // 读取params参数的第一种写法
  const {id, title, content} = useParams()
  // 读取params参数的第二种写法
  const a = useMatch('/home/message/detail/:id/:title/:content')
  console.log(a);
  return (
    <div>
      <ul>
        <li>{id}</li>
        <li>{title}</li>
        <li>{content}</li>
      </ul>
    </div>
  )
}

useSearchParams()

作用:用于读取和修改当前位置的URL中的查询字符串

返回:返回一个包含两个值得数组,内容分别为当前的search参数,更新search的函数

示例代码:

Message.jsx

import React, {useState} from 'react'
import { Link, Outlet } from 'react-router-dom'

export default function Message() {
  const [message] = useState([
    {id:'001', title:'消息001', content:'锄禾日当午'},
    {id:'002', title:'消息002', content:'汗滴禾下土'},
    {id:'003', title:'消息003', content:'谁知盘中餐'},
    {id:'004', title:'消息004', content:'粒粒皆辛苦'}
  ])
  return (
    <div>
      <ul>  
        {
          message.map((m) => {
            return <li key={m.id}>
                      <Link to={`detail?id=${m.id}&title=${m.title}&content=${m.content}`}>{m.title}</Link>&nbsp;
                    </li>
          })
        }
       
      </ul>
      <hr/>
      <Outlet/>
    </div>
  )
}

Detail.jsx

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

export default function Detail() {
  // 获取search参数的第一种
  const [search, setSearch] = useSearchParams()
  const id = search.get('id')
  const title = search.get('title')
  const content = search.get('content')
  // 获取searh参数的第二种写法
  const a = useLocation()
  console.log(a);
  return (
    <div>
      <ul>
        <li>
          <button onClick={() =>  {setSearch('id=008&title=哈哈&content=嘻嘻')}}>更新收到的参数</button>
        </li>
        <li>{id}</li>
        <li>{title}</li>
        <li>{content}</li>
      </ul>
    </div>
  )
}

useLocation()

作用:获取当前location信息,对应5中的路由组件的location属性

示例代码:

Message.jsx

import React, {useState} from 'react'
import { Link, Outlet } from 'react-router-dom'

export default function Message() {
  const [message] = useState([
    {id:'001', title:'消息001', content:'锄禾日当午'},
    {id:'002', title:'消息002', content:'汗滴禾下土'},
    {id:'003', title:'消息003', content:'谁知盘中餐'},
    {id:'004', title:'消息004', content:'粒粒皆辛苦'}
  ])
  return (
    <div>
      <ul>  
        {
          message.map((m) => {
            return <li key={m.id}>
                      <Link to='detail'
                        state={{
                          id:m.id,
                          title:m.title,
                          content:m.content
                        }}
                      >{m.title}</Link>&nbsp;
                    </li>
          })
        }
       
      </ul>
      <hr/>
      <Outlet/>
    </div>
  )
}

Detail.jsx

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

export default function Detail() {
  const {state:{id, title, content}} = useLocation()
  return (
    <div>
      <ul>
        <li>{id}</li>
        <li>{title}</li>
        <li>{content}</li>
      </ul>
    </div>
  )
}

useMatch()

作用:用于获取paramas参数

代码示例

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

export default function Detail() {
  // 读取params参数的第一种写法
  const {id, title, content} = useParams()
  // 读取params参数的第二种写法
  const a = useMatch('/home/message/detail/:id/:title/:content')
  console.log(a);
  return (
    <div>
      <ul>
        <li>{id}</li>
        <li>{title}</li>
        <li>{content}</li>
      </ul>
    </div>
  )
}

useInRouterContext()

作用:如果组件在Router的上下文中呈现,则useInRouterContext钩子返回true,否则返回false

useNavigationType()

作用:返回当前的导航类型(用户是如何来到当前页面的)

返回值有pop, push, replace

备注:pop是指在浏览器中直接打开了这个路由组件(刷新页面)

代码示例

import React from 'react'
import { useNavigationType } from 'react-router-dom'

export default function News() {
  console.log(useNavigationType());
  return (
    <div>
      <ul>
        <li>news001</li>
        <li>news002</li>
        <li>news003</li>
      </ul>
    </div>
  )
}

useOutlet()

作用:用来呈现当前组件中要渲染的嵌套路由

import React from 'react'
import { NavLink, Outlet, useOutlet} from 'react-router-dom'

export default function Home() {
  console.log('#########',useOutlet());
  return (
    <div>
      <h3>我是Home组件</h3>
      <div>
        <ul className='nav nav-item'>
          <li>
            {/* to的写法一,在父级路径下在写子级路径 */}
            {/* <NavLink className='list-group-item' to="/home/news">News</NavLink> */}
            {/* to的写法二 */}
            <NavLink className='list-group-item' to="news">News</NavLink>
          </li>
          <li>
            <NavLink className='list-group-item' to="/home/message">Message</NavLink>
          </li>
        </ul>
        {/* 指定路由组件呈现的位置 */}
        <Outlet/>
      </div>
    </div>
  )
}

useResolvedPath()

作用:给定一个URL值,解析其中的path、search、hash值

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

export default function News() {
  console.log(useNavigationType());
  console.log(useResolvedPath('/user?id=001&title=哈哈'));
  return (
    <div>
      <ul>
        <li>news001</li>
        <li>news002</li>
        <li>news003</li>
      </ul>
    </div>
  )
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
react-router-domReact框架中用于处理路由的库,它提供了一种方便的方式来管理应用程序的不同页面之间的导航和状态。而import.meta.glob是ES模块的一个新特性,它可以用于动态地导入模块。 在react-router-dom 6中,import.meta.glob可以用于动态地导入路由组件。它可以根据指定的模式匹配文件路径,并将匹配到的文件作为路由组件进行导入。这样可以方便地实现按需加载路由组件,提高应用程序的性能和加载速度。 具体使用方法如下: 1. 首先,在项目中安装react-router-dom 6: ``` npm install react-router-dom@next ``` 2. 在需要使用import.meta.glob的地方,使用如下语法进行导入: ```jsx import { lazy } from 'react'; import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; const routes = import.meta.glob('/path/to/routes/*.jsx'); function App() { return ( <Router> <Routes> {Object.entries(routes).map(([path, component]) => { const routePath = path.replace('/path/to/routes', '').replace('.jsx', ''); const LazyComponent = lazy(component); return <Route key={routePath} path={routePath} element={<LazyComponent />} />; })} </Routes> </Router> ); } export default App; ``` 在上面的代码中,`import.meta.glob('/path/to/routes/*.jsx')`会根据指定的模式匹配`/path/to/routes/`目录下的所有`.jsx`文件,并返回一个对象,其中键是文件路径,值是对应的模块。 然后,我们使用`Object.entries(routes)`将对象转换为数组,并使用`map`方法遍历数组,生成对应的`Route`组件。在遍历过程中,我们使用`lazy`函数将路由组件进行懒加载,以实现按需加载的效果。 这样,我们就可以根据文件路径动态地导入路由组件,并在应用程序中进行路由配置。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值