私はReactJSの世界に慣れていないので、アクティブなクラス名を<a>(Link)
要素ではなく<li>
要素に渡す方法を知りたいと思います。
これでこの種のコードができました。クリックするとアンカークラスが変更されます。
<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>
しかし、私は次のようなものを得たいです:
<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>
前もって感謝します
<li>
をルーター対応コンポーネントとして囲む必要があります。
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>
)
}
}
使用法:
<ul>
<NavItem to='/' index={true}>Home</NavItem>
<NavItem to='/a'>A</NavItem>
</ul>
私は、react-router-bootstrapモジュール、 https://github.com/react-bootstrap/react-router-bootstrap/blob/master/src/LinkContainer.js からインスピレーションを得ました。私はそれをテストしなかったので、それがどうなるか教えてください。
他の答えはReact Router v4で動作しないようです。以下にその方法を示します。
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
使用法:
<ul className="nav nav-tabs">
<NavItem to='/home' index={true} >Home</NavItem>
<NavItem to='/about'>About</NavItem>
</ul>
{/* 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>
<Link />
を使用する代わりに、<NavLink />
を使用しますが、同様に機能します。
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>
);
}
}
素晴らしい答え。
動作させるには、以下を変更するだけです...
LinkComponent = index ? IndexLink : Link //If its true you want an IndexLink
//Also link needs to be...
<NavItem to="/" onlyActiveOnIndex index={true}>Home</NavItem>
React Router v4.2を使用していますが、コンテキストが利用できないため、ラッピングコンポーネントからルーターオブジェクトへの参照を取得できませんでした。
これは機能しませんでした:
const { router } = this.context
@mpenの answer が好きですが、ネストされたルートを使用しており、ルーティングコンポーネントが定義されているファイルを変更したくありません。
私がやったことは、location.pathnameとを比較します:
const NavItem = withRouter(props => {
const { to, children, location } = props;
return (
<li className={location.pathname == to ? "active" : null}>
<Link to={to}>{children}</Link>
</li>
);
});
react-router-active-component で試してください。
反応またはTypeScriptバージョン間の非互換性のために、これまでの回答を簡単に機能させることはできませんでした(これは間違いなく成熟したエコシステムではありません)が、このコンポーネントはトリックを行い、li
必要に応じて:
import activeComponent from 'react-router-active-component'
let NavItem = activeComponent('li');
...
<NavItem to='/' onlyActiveOnIndex>Home</NavItem>
<NavItem to='/generate-keywords'>Generate keywords</NavItem>
React 15.1.0、react-router 2.5.0およびbootstrap 3.3(これはそれほど重要ではありません)を使用して、リンクをアクティブにするためのこのソリューションを開発しました。
npm install --save classnames
npm install --save lodash
コンポーネント:
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;
使用法:
<NavItem to="/list">List</NavItem>
私はReactの初心者なので、上記のソリューションには必ず改善が必要であり、アプローチエラーが含まれる可能性があります。ただし、有用な情報や関心のある人への出発点も含まれている場合があります。
フィードバックや提案は大歓迎です。ありがとう! :)
React Router v4)を使用して、NavLinkコンポーネント内に<li>
タグを含めることでのみ機能するようになりました。リンクをラップする<li>
タグを持つソリューションは、 HOME <li>
タグは常に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
それに応じてli
およびa
CSSセレクターを調整しました。