首页 > 解决方案 > 链接在 next.js 中无效,即使我在页面上

问题描述

我正在尝试获取链接以active在单击next.js和时上课react-bootstrap。在页面加载时,当前活动路由的链接没有被赋予活动类。当我在页面加载后单击链接时,会给出active类。我怀疑这与服务器端渲染有关。这是我的代码:

const Navigation = () => (
    <Navbar bg="warning" variant="light" collapseOnSelect expand="lg">
        <Link passHref href="/">
            <Navbar.Brand>...</Navbar.Brand>
        </Link>
        <Navbar.Toggle aria-controls="responsive-navbar-nav" />
        <Navbar.Collapse id="responsive-navbar-nav">
            <Nav className="ml-auto">
                <Link href="/">
                    <Nav.Link href="/" as="a">
                        Home
                    </Nav.Link>
                </Link>
            </Nav>
        </Navbar.Collapse>
    </Navbar>
);

export default Navigation;

页面加载 页面加载时的链接 后:手动点击链接后: 手动点击后的链接

有没有办法在服务器上突出显示链接(没有黑客解决方案)?

标签: reactjsnext.jsreact-bootstrap

解决方案


据我所知,到目前为止,无论是 NextJS 还是 react-bootstrap,都没有这样的内置功能。

下面的例子并不是一个 hacky 的解决方案,它是 NextJS 引入的最佳实践。

您需要使用一个类来显示活动链接,然后使用此功能检查当前 url 是否与 next/router 中的 url 相同:

import { useRouter } from 'next/router'
import PropTypes from 'prop-types'
import Link from 'next/link'
import React, { Children } from 'react'

const ActiveLink = ({ children, ...props }) => {
  const { asPath } = useRouter()
  const child = Children.only(children)
  const childClassName = child.props.className || ''

  // pages/index.js will be matched via props.href
  // pages/about.js will be matched via props.href
  // pages/[slug].js will be matched via props.as
  const className =
    asPath === props.href || asPath === props.as
      ? `${childClassName} active`.trim()
      : childClassName

  return (
    <Link {...props}>
      {React.cloneElement(child, {
        className: className || null,
      })}
    </Link>
  )
}

ActiveLink.propTypes = {
  activeClassName: PropTypes.string.isRequired,
}

export default ActiveLink

然后在您的组件中:

const Navigation = () => (
    <Navbar bg="warning" variant="light" collapseOnSelect expand="lg">
        <Link passHref href="/">
            <Navbar.Brand>...</Navbar.Brand>
        </Link>
        <Navbar.Toggle aria-controls="responsive-navbar-nav" />
        <Navbar.Collapse id="responsive-navbar-nav">
            <Nav className="ml-auto">
                <Link href="/">
                    <ActiveLink href="/">
                        <Nav.Link href="/" as="a">
                            Home
                        </Nav.Link>
                    </ActiveLink>
                </Link>
            </Nav>
        </Navbar.Collapse>
    </Navbar>
);

export default Navigation;

来源


推荐阅读