反応ルーターにあまり精通していませんが、li
要素ではなく親a
要素にアクティブクラスを設定するためのNavLinkの機能が必要です。
これを実装するために、NavLink
のソースコードを調べて、それを新しい要素にコピーしました。 (TypeScriptを使用した例ですが、とにかくjsとほぼ同じです)
import * as React from 'react';
import { Link, withRouter, Route } from 'react-router-dom';
class LiNavLink extends React.Component<any, {}> {
render() {
const {to,exact, strict, activeClassName, className, activeStyle, style, isActive: getIsActive, ...rest } = this.props;
return (
<Route
path={typeof to === 'object' ? to.pathname : to}
exact={exact}
strict={strict}
children={({ location, match }) => {
const isActive = !!(getIsActive ? getIsActive(match, location) : match)
return (
<li
className={isActive ? [activeClassName, className].join(' ') : className}
style={isActive ? { ...style, ...activeStyle } : style}>
<Link
to={to}
{...rest}
/>
</li>
)
}}
/>
);
}
}
export default LiNavLink;
次に使用法:
<ul>
<LiNavLink activeClassName='active' exact={true} strict to="/example"><span>Active</span></LiNavLink>
<LiNavLink activeClassName='active' exact={true} strict to="/example/archived"><span>Archived</span></LiNavLink>
</ul>
HashRouter
を使用していますが、なんらかの理由でルートが変更されても更新されません。ページを「更新」した場合にのみ、ページが更新されます。
小道具は決して変わらないので、更新されることはないと思いますか?それで、それはそれ自身を更新することを知りませんか?
これを更新するにはどうすればよいですか?それとも私の問題はどこかにありますか?
V4では、何度も試しました。
ここに私の作業コードがあります。
import React, { Component } from "react";
import logo from "../../logo.svg";
import { Link, withRouter } from "react-router-dom";
import PropTypes from "prop-types";
class Navbar extends Component {
static propTypes = {
match: PropTypes.object.isRequired,
location: PropTypes.object.isRequired,
history: PropTypes.object.isRequired
};
state = {};
getNavLinkClass = path => {
return this.props.location.pathname === path
? "nav-item active"
: "nav-item";
};
render() {
return (
<nav className="navbar navbar-expand-lg navbar-dark bg-dark">
<Link className="navbar-brand" to="/">
<img
src={logo}
width="30"
height="30"
className="d-inline-block align-top"
alt=""
/>
Utility
</Link>
<button
className="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon" />
</button>
<div className="collapse navbar-collapse" id="navbarNav">
<ul className="navbar-nav">
<li className={this.getNavLinkClass("/")}>
<Link className="nav-link" to="/">
Home
</Link>
</li>
<li className={this.getNavLinkClass("/age-counter")}>
<Link className="nav-link" to="/age-counter">
Age Counter
</Link>
</li>
</ul>
</div>
</nav>
);
}
}
export default withRouter(Navbar);
デモ作業 コードサンドボックス
私はreactを始めたばかりなので、これがベストプラクティスかどうかはわかりませんが、router v4のドキュメントを確認した後、withRouter props-> location.pathnameを使用して、ルートと比較しました。
これがNavigation.jsです:
import React from 'react';
import { withRouter } from 'react-router-dom';
import NavLink from '../General/NavLink';
const activeClass = (path, link) => {
if (path === link) {
return true;
}
return false;
};
const Navigation = props => {
const { location } = props;
return (
<ul className="menu menu--main nano-content">
<NavLink
to="/"
parentClass={
activeClass(location.pathname, '/')
? 'menu__item menu__item--active'
: 'menu__item'
}
linkClass="menu__link effect effect--waves"
>
Dashboard
</NavLink>
<NavLink
to="/users"
parentClass={
activeClass(location.pathname, '/users')
? 'menu__item menu__item--active'
: 'menu__item'
}
linkClass="menu__link effect effect--waves"
>
Users
</NavLink>
<NavLink
to="/projects"
parentClass={
activeClass(location.pathname, '/projects')
? 'menu__item menu__item--active'
: 'menu__item'
}
linkClass="menu__link effect effect--waves"
>
Projects
</NavLink>
<NavLink
href="http://google.com"
parentClass="menu__item"
linkClass="menu__link effect effect--waves"
>
Google
</NavLink>
</ul>
);
};
export default withRouter(Navigation);
そこから、子コンポーネントで使用できる親クラスと子クラスがあります。
これをチェックしてください
class LiNavLink extends React.Component<NavLinkProps> {
render() {
return (
<Route exact={this.props.exact} path={this.props.to.toString()}>
{
({ match }) =>
<li className={match ? 'active' : undefined}>
<Link to={this.props.to} >
{this.props.children}
</Link>
</li>
}
</Route>
);
}
}