Not too familiar with react router, but I need the functionality of the NavLink to set the active class on the parent li
element, and not the a
element.
To implement this I just looked at the source code of the NavLink
and copied it to a new element. (Example using typescript, but just about the same as js anyway)
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;
Then the usage:
<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>
I'm using a HashRouter
and for some reason which I can't figure out, this does not update when the route changes, only when I hard 'refresh' the page does it update how it should.
I believe it is never updating because the props never change? So it doesn't know to update itself?
How can I get this to update? Or is my problem somewhere else?
To pass data from child to parent component in React:Pass a function as a prop to the Child component. Call the function in the Child component and pass the data as arguments. Access the data in the function in the Parent .
The Route component from react-router is public by default but we can build upon it to make it restricted. We can add a restricted prop with a default value of false and use the condition if the user is authenticated and the route is restricted, then we redirect the user back to the Dashboard component.
The NavLink is used when you want to highlight a link as active. So, on every routing to a page, the link is highlighted according to the activeClassName . Link is for links that need no highlighting. And a is for external links.
In v4 after lots of tries I did.
Here my working code.
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);
Demo working Code Sandbox
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With