1,Link
作用:最终渲染为
<a>
标签,点击跳转对应路由时不刷新页面。
1.1,注意点
1,Link.to
属性,除了传递 string
之外,还可以传递 location
对象。
2,最终渲染的路由链接中,是包括 basename
的。
1.2,实现
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,NavLink
2.1,注意点
相比较 Link
组件,NavLink
组件会在路由匹配时,对生成的 <a>
标签添加 active
类名(类名)。
匹配规则受 to
,exact
,strict
,sensitive
等属性影响。
2.2,实现
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>
);
}
以上。