React路由(V6版本)

React路由学习目标:

  • 能够说出react路由的作用
  • 能够掌握react-router-dom的使用
  • 能够使用编程式导航跳转路由
  • 能够知道react路由的匹配模式

1. 路由介绍

现代的前端应用大多数是SPA(单页面应用),也就是只有一个HTML页面的应用程序。因为它的用户体验更好、对服务器的压力更小,所以更受欢迎。为了有效的使用单个页面来管理原来多页面的功能,前端路由应运而生。

  • 前端路由功能:让用户从一个视图(页面)导航到另一个视图(页面)。
  • 前端路由是一套映射规则,在react中,是url路径与组件的对应关系
  • 使用react路由简单来说,就是配置路径和组件

BroswerRouter与HashRouter的区别:

  • BroswerRouter使用 HTML5 history API 的< Router >( pushState,replaceState 和 popstate 事件),让您的 UI 同步与 URL。
  • HashRouter使用 url 中的 hash 部分来导航的路由器。(window.location.hash)。

注意:hash history 不支持 location.key 或 location.state。在以前的版本中,我们尝试对state进行匀称处理,但存在一些无法解决的极端情况。任何需要此state的代码或插件都将无法工作。由于此技术仅旨在支持旧版浏览器,因此我们建议您正确配置您的服务器并使用< BrowserRouter >

2. 路由的使用

  • 安装:yurn add react-router-dom
  • 导入路由三个核心组件:Router/Route/Link
import {BrowerRouter as Router,Routes,Route,Link} from 'react-router-dom'
  • 使用Router组件包裹整个应用
const App = () => {
	(
	<Router>
		<div id="app"></div>
	</Router>
	)
}

最基本示例:

import React from 'react'
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom'

export default function App() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/about">About</Link>
          </li>
          <li>
            <Link to="/users">Users</Link>
          </li>
        </ul>
        <Routes>
          <Route path="/about" element={<About />}></Route>
          <Route path="/users" element={<Users />}></Route>
          <Route path="/" element={<Home />}></Route>
        </Routes>
      </div>
    </Router>
  )
}

function Home() {
  return <h2>Home</h2>
}

function About() {
  return <h2>About</h2>
}

function Users() {
  return <h2>Users</h2>
}

嵌套路由示例:

import React from 'react'
import {
  BrowserRouter as Router,
  Routes,
  Route,
  Link,
  useParams,
} from 'react-router-dom'

export default function App() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/about">About</Link>
          </li>
          <li>
            <Link to="/users">Users</Link>
          </li>
          <li>
            <Link to="/topic">嵌套路由</Link>
          </li>
        </ul>
        <Routes>
          <Route path="/about" element={<About />}></Route>
          <Route path="/users" element={<Users />}></Route>
          <Route path="/topic/*" element={<Topics />}></Route>
          <Route path="/" element={<Home />}></Route>
        </Routes>
      </div>
    </Router>
  )
}

function Home() {
  return <h2>Home</h2>
}

function About() {
  return <h2>About</h2>
}

function Users() {
  return <h2>Users</h2>
}
function Topics() {
  return (
    <div>
      <h3>Topics</h3>
      <ul>
        <li>
          <Link to={'components'}>Components</Link>
          <!-- http://localhost:3000/topic/components -->
        </li>
        <li>
          <Link to={'props-v-state'}>Props v. State</Link>
          <!-- http://localhost:3000/topic/props-v-state -->
        </li>
      </ul>
      <Routes>
        <Route path={':topicId'} element={<Topic />}></Route>
        <Route path={''} element={<h3>Please select a topic.</h3>}></Route>
      </Routes>
    </div>
  )
}
function Topic() {
  let params = useParams()
  return <h4>requested topic ID:{params.topicId}</h4>
}

注意:嵌套路由后面要使用通配符“*”,且子路由不用再加上上一层路由,比如:< Link to={‘components’}>Components< /Link >,错误示例to={'/topic/components'}

更简便的嵌套路由:

import React from 'react'
import {
  BrowserRouter as Router,
  Routes,
  Route,
  Link,
  Outlet,
  useParams,
} from 'react-router-dom'

export default function App() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/about">About</Link>
          </li>
          <li>
            <Link to="/users">Users</Link>
          </li>
          <li>
            <Link to="/topic">嵌套路由</Link>
          </li>
        </ul>
        <Routes>
          <Route path="/about" element={<About />}></Route>
          <Route path="/users" element={<Users />}></Route>
          <Route path="/topic" element={<Topics />}>
            <Route path=":topicId" element={<Topic />}></Route>
          </Route>
          <Route path="/" element={<Home />}></Route>
        </Routes>
      </div>
    </Router>
  )
}

function Home() {
  return <h2>Home</h2>
}

function About() {
  return <h2>About</h2>
}

function Users() {
  return <h2>Users</h2>
}
function Topics() {
  return (
    <div>
      <h3>Topics</h3>
      <ul>
        <li>
          <Link to={'components'}>Components</Link>
        </li>
        <li>
          <Link to={'props-v-state'}>Props v. State</Link>
        </li>
      </ul>
      <Outlet></Outlet>
    </div>
  )
}
function Topic() {
  let params = useParams()
  return <h4>requested topic ID:{params.topicId}</h4>
}

两者不同点:

  • 嵌套的子路由直接写在上一层的Route中,而原本的Route的位置使用Outlet组件做占位符
    <Route path="/topic" element={<Topics />}>
       <Route path=":topicId" element={<Topic />}></Route>
    </Route>
  • Router组件:包裹整个应用,一个React应用只需使用一次
  • 两种常用Router:HashRouter和BrowerRouter
  • HashRouter:使用url的哈希值实现(http://localhost:3000/#/first)
  • (推荐)BroswerRouter:使用H5的history的API实现
  • Link组件:用于指定导航链接(a标签)
  • 所有的Route需被Routes组件包裹着

3. 路由的执行过程

  • 点击Link组件,修改了浏览器地址栏中的url
  • react路由监听到地址栏url的变化
  • react路由内部遍历所有Route组件,使用路由规则(path)与地址栏的location.pathname进行匹配
  • 当路由规则(path)能够匹配地址栏中的pathname时,就在Route组件所在的位置展示该Route组件的内容

4. 变化对比

  • < Switch >重命名为< Routes >。
  • < Route >的新特性变更。
  • 嵌套路由变得更简单。
  • 用useNavigate代替useHistory。
  • 新钩子useRoutes代替react-router-config。

第一点:

// v5
<Switch>
    <Route exact path="/"><Home /></Route>
    <Route path="/profile"><Profile /></Route>
</Switch>
 
// v6
 
import { HashRouter, Route, Routes } from "react-router-dom";
 
 <div className="App">
      <HashRouter>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/test" element={<Test />} />
        </Routes>
      </HashRouter>
  </div>

第二点:component/render被element替代

import Profile from './Profile';
 
// v5
<Route path=":userId" component={Profile} />
<Route
  path=":userId"
  render={routeProps => (
    <Profile routeProps={routeProps} animate={true} />
  )}
/>
 
// v6
<Route path=":userId" element={<Profile />} />
<Route path=":userId" element={<Profile animate={true} />} />
 

第四点:用 useNavigate 代替 useHistory

// v5
import { useHistory } from 'react-router-dom';
 
function MyButton() {
  let history = useHistory();
  function handleClick() {
    history.push('/home');
  };
  return <button onClick={handleClick}>Submit</button>;
};

// v6
import { useNavigate } from 'react-router-dom';
 
function MyButton() {
  let navigate = useNavigate();
  function handleClick() {
    navigate('/home');
  };
  return <button onClick={handleClick}>Submit</button>;
};
 

编程式导航:

// v5
history.push('/home');
history.replace('/home');
 
// v6
navigate('/home');
navigate('/home', {replace: true});

第五点:新钩子 useRoutes 代替 react-router-config

function App() {
  let element = useRoutes([
    { path: '/', element: <Home /> },
    { path: 'dashboard', element: <Dashboard /> },
    { path: 'invoices',
      element: <Invoices />,
      children: [
        { path: ':id', element: <Invoice /> },
        { path: 'sent', element: <SentInvoices /> }
      ]
    },
    // 重定向
    { path: 'home', redirectTo: '/' },
    // 404找不到
    { path: '*', element: <NotFound /> }
  ]);
  return element;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值