Reputation: 13462
So I have some files:
App.js
class App extends React.Component {
render() {
return (
<div >
<NavBar />
<Main />
</div>
);
}
}
export default App;
NavBar.js
class NavBar extends React.Component {
render() {
console.log(this.props.match)
return (
<div className="navbar-fixed">
<nav className="light-blue lighten-1">
<div className="nav-wrapper container">
<a className="brand-logo">Logo</a>
<ul id="nav-mobile" className="right hide-on-med-and-down">
<li><NavLink exact to="/characters" activeClassName="active">Characters</NavLink></li>
<li><NavLink exact to="/locations" activeClassName="active">Locations</NavLink></li>
</ul>
</div>
</nav>
</div>
);
}
}
export default withRouter(NavBar);
Main.js
class Main extends React.Component {
render() {
return (
<Switch>
<Route exact path="/characters" component={Characters}/>
<Route exact path="/locations" component={Locations}/>
</Switch>
);
}
}
export default Main;
The routing works, though in NavBar file, I have the console.log(this.props.match)
line and I always get the same path and the activeClassName
does not even work.
Whenever I change locations, the output is always:
{
path: "/",
url: "/",
params: {…},
isExact: false
}
The only thing that changes is the key isExact
.
I can access the pathname now with this.props.location
, though I have to make my own login for the active classnames to work.
Am I missing something here?
Upvotes: 1
Views: 1191
Reputation: 281912
this.props.match
gives you the match parameters for the closest matching parent and not the Route in children that is matching, since App
is at top level and matches with path='/'
, printing it in Navbar
will always return you
{
path: "/",
url: "/",
params: {…},
isExact: false
}
Now say in your case Characters
component has a subRoute(note that you should not be using exact keyword if you have nested Routes within it),which you define as
render() {
return (
<div>
{/* other stuff*/}
<Route path={`${this.props.match.path}/:characterId`} component={Character} />
</div>
)
}
In this case even though your url maybe /characters/character-1
, console.log(this.props.match)
in character component will return you
{
path: "/character",
url: "/character",
params: {…},
isExact: false
}
As far as a changing value of isExact
is considered, it returns you true of false
based on the fact the entire url matches your Route url or not
Upvotes: 1
Reputation: 9275
Using withRouter
appends the location object to the component Properties:
class NavBar extends React.Component {
// just for reference
static propTypes = {
location: PropTypes.object
}
render() {
console.log("Location", this.props.location);
return (
<div className="navbar-fixed">
<nav className="light-blue lighten-1">
<div className="nav-wrapper container">
<a className="brand-logo">Logo</a>
<ul id="nav-mobile" className="right hide-on-med-and-down">
<li><NavLink exact to="/characters" activeClassName="active">Characters</NavLink></li>
<li><NavLink exact to="/locations" activeClassName="active">Locations</NavLink></li>
</ul>
</div>
</nav>
</div>
);
}
}
export default withRouter(NavBar);
The props.location
has the shape:
{
key: 'ac3df4',
pathname: '/somewhere',
search: '?some=search-string',
hash: '#howdy',
state: {
[userDefined]: true
}
}
Upvotes: 0