如何在Next.js中创建自定义链接组件?基本上,我需要的是一个自定义链接组件,因为我必须添加一个条件onClick。为每个<Link><a onClick={handleClick}</a></Link>执行此操作将变得非常繁琐,因为将跨越多个页面使用Link。
我现在所拥有的不是很好,因为有时候在Link中已经有一个由<a>呈现的react-bootstrap标记
// components/Link.js
import Link from "next/link";
import { useContext } from "react";
import AppContext from "../../context/AppContext";
const NextLink = ({
href,
children,
replace,
scroll,
shallow,
locale,
className,
}) => {
const { someThing } = useContext(AppContext);
const handleClick = () => {
alert("clicked");
};
return (
<Link
href={href}
replace={replace}
scroll={scroll}
shallow={shallow}
locale={locale}
passHref
>
<a onClick={someThing ? handleClick : null} className={className}>
{children}
</a>
</Link>
);
};
export default NextLink;基本上,我是从上下文中获得someThing,如果它被设置为true或false。如果为真,它将运行handleClick
这就是我所需要的,但正如您可以想象的那样,当使用import Link from "next/link";时,在每个页面组件或普通组件中添加这些内容将变得非常繁琐。
一些依赖关系:
"bootstrap": "^5.1.3",
"next": "12.1.0",
"next-themes": "^0.2.0",
"react": "17.0.2",
"react-bootstrap": "^2.2.0",
"react-dom": "17.0.2",
"sass": "^1.49.9"关于新的NextLink组件会出错的地方和原因的示例:
import { useRouter } from "next/router";
import Link from "next/link";
// import NextLink from "./Link";
import { Dropdown } from "react-bootstrap";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faGlobe } from "@fortawesome/free-solid-svg-icons";
const LanguagePicker = () => {
const { locale, asPath } = useRouter();
return (
<Dropdown align={{ lg: "end" }}>
<Dropdown.Toggle
variant="outline-secondary"
id="language-dropdown"
className="px-4 py-2"
>
<FontAwesomeIcon icon={faGlobe} className="me-2" />
{locale === "en" ? "EN" : "ES"}
</Dropdown.Toggle>
<Dropdown.Menu>
<Link href={asPath} locale="es" passHref>
<Dropdown.Item className={locale === "es" ? "active" : ""}>
Español
</Dropdown.Item>
</Link>
<Link href={asPath} locale="en" passHref>
<Dropdown.Item className={locale === "en" ? "active" : ""}>
English
</Dropdown.Item>
</Link>
</Dropdown.Menu>
</Dropdown>
);
};
export default LanguagePicker;如果我现在将<Link>替换为<NextLink>,它将因为<Dropdown.Item>而呈现2个<a>标记。
发布于 2022-05-27 10:05:31
您可以将以下自定义组件链接到:
import NextLink from "next/link";
export default function Link({ onClick, children, ...rest }) {
return (
<NextLink {...rest} passHref>
<a
onClick={
onClick
? (e) => {
e.preventDefault();
onClick();
}
: undefined
}
>
{children}
</a>
</NextLink>
);
}像这样使用它,没有onClick
import {Link} from "components/link";
<Link href={"/about"}>About</Link>用onClick
<Link href={"/about"} onClick={() => alert("test")}>About</Link>在Dropdown中,使用防止双重<a>元素的DropDown.ItemText:
<Link href={"/"} onClick={() => alert("test")}>
<Dropdown.ItemText>English</Dropdown.ItemText>
</Link>如果您想要自动添加onClick,下面是如何修改组件的方法:
import NextLink from "next/link";
export default function Link({ onClick, children, ...rest }) {
let clickHandler = onClick;
if (!clickHandler) {
const shouldAddOnClick = /* Code that decides if onClick needs to be added */;
if (shouldAddOnClick) {
clickHandler = () => {/* ... */};
}
}
return (
<NextLink {...rest} passHref>
<a
onClick={
clickHandler
? (e) => {
e.preventDefault();
clickHandler();
}
: undefined
}
>
{children}
</a>
</NextLink>
);
}https://stackoverflow.com/questions/72398138
复制相似问题