question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Pass current props to NavLink.props.isActive()

See original GitHub issue

Description of Problem

In my app I have some navigation UI that looks like this:

There are routes something like this:

# Examples of routes
/locations
/location/{id}
/organizations
/organization/{id}
/users
/users/{id}
etc...

I would like for these globally visible links to appear active both at the route that literally matches their given link, but also at the route representing the singular entity of the corresponding kind.

For example, “Location” is active both at /locations and at /location/{id}

Desired API

This would be trivially implemented by giving the isActive function access to the other NavLink props. Then, isActive could test against the to prop, or anything else aribitrarily.

For example:

<NavLink to="/location" isActive={(match,location,{to}) => location.pathname.includes(to))}

It’s impossible to generalize this idea without access to the props, since the necessary information with which to generalize is NavLink.props.to.

Example of Problem

For example, in order to implement this with the existing API, you must manually specify the regex in every NavLink:

// notice that this isActive function can't be written just once for all of these cases
<NavLink to="/locations" isActive={(match,location) => /location/.test(location.pathname)}
<NavLink to="/organizations" isActive={(match,location) => /organization/.test(location.pathname)}
<NavLink to="/users" isActive={(match,location) => /user/.test(location.pathname)}

Actionable Idea

It looks like an easy PR that would not break any existing behavior. What are your thoughts?

In the NavLink component you can see that isActive receives match, and location.

      const isActive = !!(getIsActive ? getIsActive(match, location) : match) <----

      return (
        <Link
          to={to}
          className={isActive ? [ className, activeClassName ].filter(i => i).join(' ') : className}
          style={isActive ? { ...style, ...activeStyle } : style}
          aria-current={isActive && ariaCurrent}
          {...rest}
        />

I’m imagining the change looks like this:

      const isActive = !!(getIsActive ? getIsActive(match, location, props) : match)

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:3
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
timdorrcommented, Jul 26, 2017

This will probably get pushback because you can do this yourself already:

export const LooseNavLink = props => (
  <NavLink {...props} isActive={(match, location) => location.pathname.startsWith(props.to.pathname)}/>
)

In general, the consensus is to avoid adding things to the APIs if they are already possible without too much difficulty. We’re trying not to grow the API surface, because it’s very hard to roll back changes and it makes future improvements harder to do.

I know this is just one arg on one prop on one component, but it’s meant as a philosophy for development so that we don’t suffer a death by a thousand cuts. Same thing happened with v1-v3, so we want to avoid that.

0reactions
dovidweiszcommented, Nov 30, 2018

@timdorr : This is why I would prefer of you implemented this change:

https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md

A bind call or arrow function in a JSX prop will create a brand new function on every single render. This is bad for performance, as it will result in the garbage collector being invoked way more than is necessary. It may also cause unnecessary re-renders if a brand new function is passed as a prop to a component that uses reference equality check on the prop to determine if it should update.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Pass current props to NavLink.props.isActive() #5376 - GitHub
Description of Problem In my app I have some navigation UI that looks like this: There are routes something like this: # Examples...
Read more >
How can I pass the "isActive" prop from NavLink to its children?
OP is trying to pass an active prop based on the isActive state of the NavLink to the child SelectedContainerIcon component. · I...
Read more >
NavLink - React Router: Declarative Routing for React.js
This will be joined with the className prop. <NavLink to="/faq" ... The isActive compares the current history location (usually the current browser URL)....
Read more >
Active NavLink Classes with React Router - Ultimate Courses
Our <NavLink> component provides an isActive property that contains a boolean value, which is exposed to us through the className attribute when ...
Read more >
isActive prop - React Router Quick Start Guide [Book] - O'Reilly
The isActive prop is used to determine whether the <NavLink> component should have the active class applied (or inline styles specified in activeStyle...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found