React@16.x(50)路由v5.x(15)源码(7)- 实现 Link 和 NavLink

目录

作用 :最终渲染为 <a> 标签,点击跳转对应路由时不刷新页面。

1.1,注意点

1,Link.to 属性,除了传递 string 之外,还可以传递 location 对象。

2,最终渲染的路由链接中,是包括 basename 的。

1.2,实现

js 复制代码
import React from "react";
import ctx from "../react-router/RouterContext";
import { parsePath } from "history";

export function Link(props) {
    const { to, ...rest } = props;
    return (
        <ctx.Consumer>
            {(value) => {
                let _location = {};
                if (typeof to === "object") {
                    _location = to;
                } else {
                    // 将路径字符串,转为 location 对象。
                    _location = parsePath(to);
                }
                // 通过 location 对象创建一个可用于 a 标签的链接(会自动拼接 basename)。
                const _href = value.history.createHref(_location);
                return (
                    <a
                        href={_href}
                        {...rest}
                        onClick={(e) => {
                            e.preventDefault();
                            value.history.push(_location);
                        }}
                    >
                        {props.children}
                    </a>
                );
            }}
        </ctx.Consumer>
    );
}

2.1,注意点

相比较 Link 组件,NavLink 组件会在路由匹配时,对生成的 <a> 标签添加 active 类名(类名)。

匹配规则受 toexactstrictsensitive 等属性影响。

2.2,实现

js 复制代码
import React from "react";
import { parsePath } from "history";
import { Link } from "./Link";
import ctx from "../react-router/RouterContext";
import matchPath from "../react-router/matchPath";

export function NavLink(props) {
    const { activeClass = "active", exact = false, strict = false, sensitive = false, ...rest } = props;
    return (
        <ctx.Consumer>
            {({ location }) => {
                let _location = {};
                if (typeof props.to === "object") {
                    _location = props.to;
                } else {
                    // 将路径字符串,转为 location 对象。
                    _location = parsePath(props.to);
                }
                const matched = matchPath(_location.pathname, location.pathname, { exact, strict, sensitive });
                if (matched) {
                    return <Link className={activeClass} {...rest}></Link>;
                } else {
                    return <Link {...rest}></Link>;
                }
            }}
        </ctx.Consumer>
    );
}

以上。

相关推荐
子兮曰2 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰2 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万2 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝2 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋2 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁2 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄2 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95272 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大2 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师2 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端