web-dev-qa-db-fra.com

Cibler le lien actif lorsque l'itinéraire est actif dans Next.js

Comment cibler le lien actif dans Next.js comme ils le font dans React-Router-4? Signification, donner au lien actif une classe lorsque son itinéraire est actif?

6
Ruby

Tout d'abord, vous devez avoir un composant appelé Link, avec l'attribut temporaire activeClassName

import { withRouter } from 'next/router'
import Link from 'next/link'
import React, { Children } from 'react'

const ActiveLink = ({ router, children, ...props }) => {
  const child = Children.only(children)

  let className = child.props.className || null
  if (router.pathname === props.href && props.activeClassName) {
    className = `${className !== null ? className : ''} ${props.activeClassName}`.trim()
  }

  delete props.activeClassName

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

export default withRouter(ActiveLink)

Ensuite, disposez d'une barre de navigation avec le lien créé et le sélecteur css :active pour différencier le lien actif du lien inactif.

import Link from './Link'

export default () => (
  <nav>
    <style jsx>{`
      .active:after {
        content: ' (current page)';
      }
      .nav-link {
        text-decoration: none;
        padding: 10px;
        display: block;
      }
    `}</style>

    <ul>
      <li>
        <Link activeClassName='active' href='/'>
          <a className='nav-link home-link'>Home</a>
        </Link>
      </li>
      <li>
        <Link activeClassName='active' href='/about'>
          <a className='nav-link'>About</a>
        </Link>
      </li>
    </ul>
  </nav>
)

Après cela, vous pouvez implémenter la barre de navigation sur votre page:

import Nav from '../components/Nav'

export default () => (
  <div>
    <Nav />
    <p>Hello, I'm the home page</p>
  </div>
)

La clé de la façon dont cela fonctionne est située à l'intérieur du composant Link, nous comparons la valeur de router.pathname avec l'attribut href du lien, si la valeur correspond à l'autre, mettez un nom de classe spécifique pour que le lien soit activé.

Référence: ici

6
Darryl R. Norbert

Une autre version minimale qui prend en charge as prop:

import Link from "next/link";
import {withRouter} from "next/router";
import {Children} from "react";
import React from "react";

export default withRouter(({router, children, as, href, ...rest}) => (
   <Link {...rest} href={href} as={as}>
      {React.cloneElement(Children.only(children), {
         className: (router.asPath === href || router.asPath === as) ? `active` : null
      })}
   </Link>
));
8
Saman Mohamadi