web-dev-qa-db-fra.com

Comment qualifier le lien actif dans react-router v4?

Dans react-router v3, nous avions activeStyle et activeClassName pour appeler Active Link.

nous pourrions faire quelque chose comme ça

  <div id="tags-container">
    {tags.map(t =>
      <Link
        className="tags"
        activeStyle={{ color: 'red' }}
        to={t.path}
      >
        {t.title}
      </Link>
    )}
  </div>

Je veux savoir comment puis-je faire la même chose dans la v4?

30
Ramtin Khalatbari

Utilisez NavLink à la place de Link. Ce n'est pas documenté, mais c'est le travail que vous attendez. https://github.com/ReactTraining/react-router/issues/4318

MISE À JOUR 17.05.2017:

https://reacttraining.com/react-router/web/api/NavLink

26
Sergey Reutskiy

Vous pouvez le faire avec NavLink dans react-router v4

 <div id="tags-container">
   {tags.map(t =>
     <NavLink
       className="tags"
       activeStyle={{ color: 'red' }}
       to={t.path}
     >
       {t.title}
     </NavLink>
   )}
 </div>
13
Gapur Kassym

Si vous rencontrez un problème où votre menu de navigation fonctionne sauf qu'il ne se met pas à jour correctement lorsque vous cliquez sur des liens et que la route change, mais cela fonctionne correctement si vous appuyez sur F5, vous pouvez faire ceci:

Ceci est probablement dû au fait que vous utilisez Redux qui utilise une méthode shouldComponentUpdate Lifecycle sur sa fonction connect. Votre composant Nav est probablement encapsulé dans connect. C'est tout bon. shouldComponentUpdate est ce qui ruine votre vie.

Pour résoudre ce problème, amenez simplement le routeur dans votre fonction mapStateToProps:

// This lets shouldComponentUpdate know that the route changed,
// which allows the Nav to re-render properly when the route changes, woot!
const mapStateToProps = (state) => {
  return {
    router: state.router,
  }
}

// or, if you prefer pro style destructure shorthand:
const mapStateToProps = ({ router }) => ({ router })

Si vous ne savez pas trop où state.router vient de, il provient du fichier dans lequel vous combinez vos réducteurs, et vous verrez quelque chose comme ceci:

import { combineReducers } from 'redux'
import { routerReducer } from 'react-router-redux'
import authReducer from './components/auth/auth_reducer'

export default combineReducers({
  router: routerReducer,
  auth: authReducer,
})

Voici un peu de HTML et de CSS pour une jolie baller Nav Link:

HTML

<ul id="Nav_menu">
  <li>
    <NavLink
      to="/home"
      className="Nav_link"
      activeClassName="activeRoute"
      activeStyle={{ color: 'teal' }}
    >
      HOME
    </NavLink>
  </li>
  <li>
    <NavLink
    to="/products"
    className="Nav_link"
    activeClassName="activeRoute"
    activeStyle={{ color: 'teal' }}
    >
      PRODUCTS
    </NavLink>
  </li>
</ul>

REMARQUE: Si vous vous connectez à "/", mettez exact prop sur NavLink.

CSS

#Nav_menu {
  display: flex;
  flex-direction: row;
  width: 100%;
  height: 100%;
  list-style-type: none;
  margin: 0;
  padding: 0;
}

.Nav_link:link {
  color: #fff;
  font-size: 1.6rem;
  line-height: 1.6rem;
  text-decoration: none;
}
.Nav_link:visited {
  color: #fff;
}
.Nav_link:hover {
  color: yellow;
}
.Nav_link:active {
  color: teal;
}

.activeRoute {
  background-color: yellow;
  border-bottom: 0.4rem solid teal;
  cursor: not-allowed;
}

Remarquez activeStyle dans le balisage HTML. C'était la seule façon pour moi de changer la couleur du texte sur la route/le lien actif. Cela n'a pas fonctionné quand j'ai mis color: teal; dans la classe activeRoute CSS. Ouvrez ceci dans un autre onglet: https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/NavLink.md

Si vous ne savez pas pourquoi j'ai utilisé rem au lieu de px. C’est une excellente occasion pour vous de rechercher l’accessibilité et la base du Web font-size: 10px;.

Restez en forme et amusez-vous.

6
agm1984

Cet exemple tiré de react-router v4 documentation de lien personnalisée vous aidera à le réaliser:

const OldSchoolMenuLink = ({ label, to, activeOnlyWhenExact }) => (
  <Route path={to} exact={activeOnlyWhenExact} children={({ match }) => (
    <div className={match ? 'active' : ''}>
      {match ? '> ' : ''}<Link to={to}>{label}</Link>
    </div>
  )}/>
);

Donc, dans votre cas, vous pourriez créer le composant suivant:

const CustomLink = ({ activeStyle, children, className, to, activeOnlyWhenExact }) => (
  <Route path={to} exact={activeOnlyWhenExact} children={({ match }) => (
    <Link to={to} className={className} style={match && activeStyle}>{children}</Link>
  )}/>
);

Et puis l'utiliser comme:

  <div id="tags-container">
    {tags.map(t =>
      <CustomLink
        className="tags"
        activeStyle={{ color: 'red' }}
        to={t.path}
      >
        {t.title}
      </Link>
    )}
  </div>
3
glennreyes

Développer sur réponse de @ agm1984 : La solution de NavLinks ne met pas à jour correctement les styles, qui utilisait routerReducer de react-router-redux, n'a pas fonctionné pour moi. Au lieu de cela, j'ai découvert que le problème était que connect wrapper utilisait shouldComponentUpdate et empêchait le rendu du composant contenant NavLinks.

La solution correcte dans ma situation était de passer l'objet options à connect comme 4ème paramètre, comme indiqué ci-dessous:

export default connect(mapStateToProps, null, null, { pure: false })(NavItems);
3
MrSegFaulty

Tout fonctionne toujours de la même manière. Cependant, react-router-dom v4 remplace Link par NavLink

import { NavLink as Link } from 'react-router-dom'; va aussi bien. Remarque: Navlinks est activé par défaut pour que vous puissiez styler a:active ou activeStyle={{color: 'red'}}

1
Alisher Musurmonv