如何在Gatsby的Navbar组件中正确区分内外部链接并消除警告
我正在制作个人作品集网站,已创建Navbar组件,包含首页、项目页、博客页的链接,其中首页和博客页为内部链接,项目页为外部链接。
当前实现代码如下:
import * as React from 'react'; import { Link, useStaticQuery, graphql } from 'gatsby'; import Icon from '../images/icon.svg'; const Navbar = ({pageTitle}) => { const data = useStaticQuery(graphql` query { site { siteMetadata { title } } } `); const menu = [ { title: 'HOME', path:'/' }, { title: 'PRØJECTS', path: 'https://github.com/chukkyiii?tab=repositories' }, { title: 'BLØG', path: '/blog' } ] return ( <main> <title> {pageTitle} | {data.site.siteMetadata.title} </title> <div> <div className="mx-auto mb-9 flex items-center justify-between max-w-2xl "> <Icon className="w-12 h-12 p-1 rounded-full ring-2 ring-gray-300 dark:ring-gray-500" /> <nav> <ul className="flex"> {menu.map((item) => ( <li key={item.title}> <Link to={item.path} className="pl-8 hover:text-amber-500"> {item.title} </Link> </li> ))} </ul> </nav> </div> </div> </main> ); } export default Navbar;
通过数组循环使用Link组件渲染所有链接以避免重复代码,功能可正常运行,但触发了如下警告:
react_devtools_backend.js:4026 External link https://github.com/chukkyiii?tab=repositories was detected in a Link component. Use the Link component only for internal links. See: https://gatsby.dev/internal-links
请问有没有其他实现方式可以消除该警告?
解决方法
核心逻辑是区分内部/外部链接,分别使用Gatsby的Link组件和原生<a>标签,同时保留数组循环的写法避免重复代码,以下是几种可行方案:
方案1:给菜单项添加外部链接标识
修改菜单数组,手动标记哪些是外部链接:
const menu = [ { title: 'HOME', path:'/', isExternal: false }, { title: 'PRØJECTS', path: 'https://github.com/chukkyiii?tab=repositories', isExternal: true }, { title: 'BLØG', path: '/blog', isExternal: false } ]
循环渲染时根据标识切换组件:
{menu.map((item) => ( <li key={item.title}> {item.isExternal ? ( <a href={item.path} className="pl-8 hover:text-amber-500" target="_blank" rel="noopener noreferrer" > {item.title} </a> ) : ( <Link to={item.path} className="pl-8 hover:text-amber-500"> {item.title} </Link> )} </li> ))}
方案2:自动识别外部链接
无需手动标记,通过判断路径是否以http开头自动识别外部链接:
{menu.map((item) => ( <li key={item.title}> {item.path.startsWith('http') ? ( <a href={item.path} className="pl-8 hover:text-amber-500" target="_blank" rel="noopener noreferrer" > {item.title} </a> ) : ( <Link to={item.path} className="pl-8 hover:text-amber-500"> {item.title} </Link> )} </li> ))}
方案3:封装通用链接组件(可维护性优化)
如果后续链接样式或逻辑需要统一修改,可封装一个通用组件复用判断逻辑:
// 新建通用链接组件 const LinkOrAnchor = ({ to, children, ...props }) => { if (to.startsWith('http')) { return ( <a href={to} {...props} target="_blank" rel="noopener noreferrer" > {children} </a> ) } return <Link to={to} {...props}>{children}</Link> } // 在Navbar中使用 {menu.map((item) => ( <li key={item.title}> <LinkOrAnchor to={item.path} className="pl-8 hover:text-amber-500"> {item.title} </LinkOrAnchor> </li> ))}
内容的提问来源于stack exchange,提问作者chebz
相关产品推荐
相关产品推荐

