Je suis nouveau dans le monde de ReactJS et voudrais savoir comment puis-je transmettre le nom de la classe active à l'élément <li>
au lieu de l'élément <a>(Link)
.
Maintenant, j'ai ce genre de code. La classe d'ancrage change lorsque vous cliquez dessus.
<li><IndexLink to='/' activeclassName='active'>A</IndexLink></li>
<li><Link to='/b' activeclassName='active'>B</Link></li>
<li><Link to='/c' activeclassName='active'>C</Link></li>
Mais j'aimerais avoir quelque chose de similaire à:
<li activeclassName='active'><IndexLink to='/'>A</IndexLink></li>
<li activeclassName='active'><Link to='/b'>B</Link></li>
<li activeclassName='active'><Link to='/c'>C</Link></li>
Merci d'avance
Vous devez inclure votre <li>
en tant que composant sensible au routeur:
import { Link, IndexLink } from 'react-router'
class NavItem extends React.Component {
render () {
const { router } = this.context
const { index, onlyActiveOnIndex, to, children, ...props } = this.props
const isActive = router.isActive(to, onlyActiveOnIndex)
const LinkComponent = index ? Link : IndexLink
return (
<li className={isActive ? 'active' : ''}>
<LinkComponent {...props}>{children}</LinkComponent>
</li>
)
}
}
Usage:
<ul>
<NavItem to='/' index={true}>Home</NavItem>
<NavItem to='/a'>A</NavItem>
</ul>
Je suis inscrit au module react-router-bootstrap, https://github.com/react-bootstrap/react-router-bootstrap/blob/master/src/LinkContainer.js . Je ne l'ai pas testé, alors laissez-moi savoir comment ça se passe.
Les autres réponses ne semblent pas fonctionner dans React Router v4. Voici comment vous pouvez le faire:
import React, {PropTypes} from 'react'
import {Route, Link} from 'react-router-dom'
import styles from './styles.less';
export default function NavItem({children, to, exact}) {
return (
<Route path={to} exact={exact} children={({match}) => (
<li className={match ? styles.activeRoute : null}>
<Link to={to}>{children}</Link>
</li>
)}/>
)
}
NavItem.propTypes = {
to: PropTypes.string.isRequired,
exact: PropTypes.bool,
children: PropTypes.node.isRequired,
};
/**
* A navigation component
*/
import React, { Component } from 'react'
import { Link, IndexLink, withRouter } from 'react-router'
import styles from './styles.scss'
class NavItem extends Component {
render () {
const { router } = this.props
const { index, to, children, ...props } = this.props
let isActive
if( router.isActive('/',true) && index ) isActive = true
else isActive = router.isActive(to)
const LinkComponent = index ? IndexLink : Link
return (
<li className={isActive ? 'active' : ''}>
<LinkComponent to={to} {...props}>{children}</LinkComponent>
</li>
)
}
}
NavItem = withRouter(NavItem)
export default NavItem
Usage:
<ul className="nav nav-tabs">
<NavItem to='/home' index={true} >Home</NavItem>
<NavItem to='/about'>About</NavItem>
</ul>
Au lieu d'utiliser <Link />
, j'utilise <NavLink />
et cela fonctionne aussi bien.
import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
//.....
export default class AppNav extends Component {
render (){
return (
<header>
<ul className="main-nav">
<li><NavLink activeClassName={"active"} exact={true} to="/">Home</NavLink></li>
<li><NavLink activeClassName={"active"} to="/about">About</NavLink></li>
<li><NavLink activeClassName={"active"} to="/courses">Courses</NavLink></li>
</ul>
</header>
);
}
}
{/* Make sure that `location` is injected into this component */}
<ul className="nav navbar-nav">
<li className={location.pathname === '/' && 'active'}>
<Link to='/'>
Home page
</Link>
</li>
<li className={location.pathname.startsWith('/about') && 'active'}>
<Link to='/about'>
About us
</Link>
</li>
</ul>
Très bonne réponse.
Il suffit de changer ce qui suit pour le faire fonctionner ...
LinkComponent = index ? IndexLink : Link //If its true you want an IndexLink
//Also link needs to be...
<NavItem to="/" onlyActiveOnIndex index={true}>Home</NavItem>
Essayez avec react-router-active-composant .
Aucune des réponses précédentes ne fonctionnait facilement en raison d'incompatibilités entre les versions de réaction et de TypeScript (il ne s'agit certainement pas d'un écosystème mature), mais ce composant a fait l'affaire et peut être appliqué à d'autres éléments que li
si nécessaire:
import activeComponent from 'react-router-active-component'
let NavItem = activeComponent('li');
...
<NavItem to='/' onlyActiveOnIndex>Home</NavItem>
<NavItem to='/generate-keywords'>Generate keywords</NavItem>
En utilisant react 15.1.0, react-router 2.5.0 et bootstrap 3.3 (c'est moins important), j'ai développé cette solution pour rendre les liens actifs:
npm install --save classnames
npm install --save lodash
Le composant:
import React from 'react';
import { Link, IndexLink } from 'react-router';
import _ from 'lodash';
import classnames from 'classnames';
class NavItem extends React.Component {
constructor(props) {
super(props);
// The default state
this.state = {
isActive: false,
unregisterRouteListener: false
};
// Binding for functions
this.locationHasChanged = this.locationHasChanged.bind(this);
}
componentDidMount() {
// Check if component is active on mount and add listener on route change
this.setState({
isActive: this.context.router.isActive(this.props.to, true),
unregisterRouteListener: this.context.router.listen(this.locationHasChanged)
});
}
componentWillUnmount() {
if (this.state.unregisterRouteListener) {
// Remove the listener
this.state.unregisterRouteListener();
}
// Reset the state
this.setState({
isActive: false,
unregisterRouteListener: false
});
}
// Update the state of the component, based on the router path
locationHasChanged() {
this.setState({
isActive: this.context.router.isActive(this.props.to, true)
});
}
render () {
let { index } = this.props;
let LinkComponent = index ? Link : IndexLink;
let newProps = _.omit(this.props, 'router');
return (
<li className={classnames('', this.state.isActive ? 'active' : '' )}>
<LinkComponent {...newProps}>
{this.props.children}
</LinkComponent>
</li>
);
}
}
NavItem.contextTypes = {
router: React.PropTypes.object
};
export default NavItem;
Usage:
<NavItem to="/list">List</NavItem>
Je suis un débutant avec React, la solution ci-dessus a donc sûrement besoin d’être améliorée et peut contenir des erreurs d’approche. Cependant, il peut également contenir des informations utiles ou un point de départ pour les personnes intéressées.
Tous les commentaires ou suggestions sont plus que bienvenus. Merci! :)
En utilisant React Router v4, je l’ai seulement obtenu en incluant les balises <li>
dans le composant NavLink. Les solutions dont les balises <li>
encapsulent les liens ont pour résultat que la balise HOME <li>
a toujours la classe active
.
import React from 'react'
import { NavLink } from 'react-router-dom';
class Header extends React.Component {
render() {
return (
<div>
<header>
<nav>
<ul>
<NavLink activeClassName={"active"} exact={true} to="/"><li>Home</li></NavLink>
<NavLink activeClassName={"active"} to="/about"><li>About</li></NavLink>
<NavLink activeClassName={"active"} to="/courses"><li>Courses</li></NavLink>
</ul>
</nav>
</header>
</div>
)
}
}
export default Header
J'ai ajusté les sélecteurs CSS li
et a
en conséquence.
J'utilise React Router v4.2 et je n'ai pas pu obtenir la référence à l'objet routeur à partir du composant d'habillage, car le contexte n'est pas disponible.
Cela n'a pas fonctionné:
const { router } = this.context
J'aime @/mpen's answer , mais j'utilise des itinéraires imbriqués et je ne souhaite pas modifier le fichier dans lequel le composant de routage est défini.
Ce que j'ai fait est comparé le location.pathname avec à:
const NavItem = withRouter((props) => {
const { to, children, location } = props;
return (
<li className={location.pathname == to ? 'active' : null}>
<Link to={to}>{children}</Link >
</li>
)});