Ich bin neu in der ReactJS-Welt und möchte wissen, wie ich einen aktiven Klassennamen an das <li>
-Element anstelle des <a>(Link)
-Elements übergeben kann.
Jetzt habe ich diese Art von Code. Die Ankerklasse ändert sich, wenn Sie darauf klicken.
<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>
Aber ich würde gerne etwas Ähnliches bekommen:
<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>
Danke im Voraus
Sie müssen Ihren <li>
als Komponente für den Router angeben:
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>
)
}
}
Verwendungszweck:
<ul>
<NavItem to='/' index={true}>Home</NavItem>
<NavItem to='/a'>A</NavItem>
</ul>
Ich habe die Inspration vom Reakt-Router-Bootstrap-Modul https://github.com/react-bootstrap/react-router-bootstrap/blob/master/src/LinkContainer.js übernommen. Ich habe es jedoch nicht getestet, also lassen Sie mich wissen, wie es läuft.
Die anderen Antworten scheinen in React Router v4 nicht zu funktionieren. So kannst du es machen:
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
Verwendungszweck:
<ul className="nav nav-tabs">
<NavItem to='/home' index={true} >Home</NavItem>
<NavItem to='/about'>About</NavItem>
</ul>
Anstelle von <Link />
benutze ich <NavLink />
und es funktioniert auch.
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>
Gute Antwort.
Ändern Sie einfach das Folgende, damit es funktioniert ...
LinkComponent = index ? IndexLink : Link //If its true you want an IndexLink
//Also link needs to be...
<NavItem to="/" onlyActiveOnIndex index={true}>Home</NavItem>
Versuchen Sie es mit Reactor-Router-Active-Component .
Ich konnte keine der vorherigen Antworten erhalten, die aufgrund von Inkompatibilitäten zwischen den Versionen reagieren oder TypeScript-Versionen (dies ist definitiv kein ausgereiftes Ökosystem) funktioniert, aber diese Komponente hat den Trick und kann bei Bedarf auf andere Elemente als li
angewendet werden:
import activeComponent from 'react-router-active-component'
let NavItem = activeComponent('li');
...
<NavItem to='/' onlyActiveOnIndex>Home</NavItem>
<NavItem to='/generate-keywords'>Generate keywords</NavItem>
Unter Verwendung von 15.1.0, Reakt-Router 2.5.0 und Bootstrap 3.3 (das ist weniger wichtig) habe ich diese Lösung entwickelt, um die Links zu aktivieren:
npm install --save classnames
npm install --save lodash
Die Komponente:
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;
Verwendungszweck:
<NavItem to="/list">List</NavItem>
Ich bin ein Anfänger von React, daher muss die oben genannte Lösung sicherlich verbessert werden und möglicherweise Annäherungsfehler enthalten. Es kann jedoch auch nützliche Informationen oder einen Ausgangspunkt für Interessierte enthalten.
Feedback oder Anregungen sind mehr als willkommen. Vielen Dank! :)
Mit React Router v4 habe ich es nur zur Wirkung gebracht, indem die <li>
-Tags in die NavLink-Komponente aufgenommen wurden. Die Lösungen, bei denen die <li>
-Tags die Links umschließen, führten dazu, dass der HOME <li>
-Tag immer die active
-Klasse hat.
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
Ich habe die CSS-Selektoren li
und a
entsprechend angepasst.
Ich verwende React Router v4.2 und konnte den Verweis auf das Routerobjekt nicht von der Wrapping-Komponente abrufen, da der Kontext nicht verfügbar ist.
Das hat nicht funktioniert:
const { router } = this.context
Ich mag @ mpens answer , aber ich verwende verschachtelte Routen und möchte nicht die Datei ändern, in der ich die Routingkomponente definiert habe.
Was ich getan habe, ist den location.pathname mit zu vergleichen:
const NavItem = withRouter((props) => {
const { to, children, location } = props;
return (
<li className={location.pathname == to ? 'active' : null}>
<Link to={to}>{children}</Link >
</li>
)});