react-router-dom使用及源码实现

React-router-dom 是专门用于web应用的路由解决方案。

1、Router、Link、Route

1.1、基本使用

首先编写一个简单的示例:

import React from "react";
import {
   
  BrowserRouter as Router,
  Route,
  Link
} from "react-router-dom";

export default function App() {
   
  return (
    <div className="App">
      <Router>
        <Link to="/">首页</Link>
        <Link to="/user">用户中心</Link>
        <Link to="/login">登录</Link>
        <Link to="/product/123">商品</Link>

        <Route
          path="/"
          children={
   () => HomePage({
    data: "children" })}
          component={
   HomePage}
          render={
   () => <HomePage data="render" />}
        />
        <Route path="/user" component={
   UserPage} />
        <Route path="/login" component={
   LoginPage} />
      </Router>
    </div>
  );
}

function HomePage(props) {
   
  console.log("index", props);
  return <div>首页 - {
   props.data}</div>;
}

function UserPage(props) {
   
  return <div>用户中心</div>;
}

function LoginPage(props) {
   
  return <div>登录</div>;
}

示例中使用了 react-router-dom 的三个组件 BrowserRouterRouteLink

Router 组件就好比路由器,Link 就是路由器的网线接口和网线,Route 就是和路由器连接的各种设备。

有了路由器,网线和设备才有存在的意义,所以 Route 和 Link 组件必须放在 Router 组件中。

Link 组件的 to 属性指定了点击该链接后会跳转的路由,Route 组件的 path 属性指定了该 Route 组件会匹配的路由,如果匹配上了就渲染 children , component , render 属性指定的组件(这三个属性都是用来指定待渲染组件的),三者区别如下:

children

即使路由不匹配也会渲染出指定的组件

component

只有路由匹配了才会渲染出指定组件,最好不要采用内联函数的方式传值,这样会导致每次重新渲染都会生成新的组件进行挂载,卸载之前的组件,而不是在之前组件上进行更新。如果要使用内联函数的形式,最好使用 render 或 children

render

适合传递内联函数,在路由匹配时执行该函数

三者的优先级为 children > component > render

1.2、源码实现

要想实现路由相关组件,我们需要借助一个库 history,这个库提供了一个方法 createBrowserHistory,可以用来创建一个 history 对象,保存路由历史记录等信息,也可以监听路由变化。

1.2.1 Link 组件

先从最简单的开始,那就是 Link 组件,Link 组件的实质就是一个 a 标签

<Link to="/">首页</Link>
<Link to="/user">用户中心</Link>
<Link to="/login">登录</Link>
<Link to="/product/123">商品</Link>

在这里插入图片描述

import {
    useContext } from "react";
import RouterContext from "./RouterContext";

export default function Link(props) {
   
  const {
    to, children } = props;
  const context = useContext(RouterContext);

  function onClick(e) {
   
    // 阻止默认行为
    e.preventDefault();
    // 使用 Router 组件传递的 context 中的 history 对象来改变路由
    context
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值