Skip to content

Conversation

@nicksrandall
Copy link

This PR exposes the isActive logic from NavLink as a hook so that it can be used to create custom NavLink style components.

Example usage:

import { usePathIsActive, Link } from 'react-router-dom';
import { Button } from '@chakra-ui/react';

function NavButton({ to }) {
  const isActive = usePathIsActive({ to });
  return (
    <Button as={Link} to={to} colorScheme={isActive ? 'blue' : 'gray'}>My fancy page</Button>
  )
}

@remix-cla-bot
Copy link
Contributor

remix-cla-bot bot commented Mar 16, 2022

Hi @nicksrandall,

Welcome, and thank you for contributing to React Router!

Before we consider your pull request, we ask that you sign our Contributor License Agreement (CLA). We require this only once.

You may review the CLA and sign it by adding your name to contributors.yml.

Once the CLA is signed, the CLA Signed label will be added to the pull request.

If you have already signed the CLA and received this response in error, or if you have any questions, please contact us at [email protected].

Thanks!

- The Remix team

@remix-cla-bot
Copy link
Contributor

remix-cla-bot bot commented Mar 16, 2022

Thank you for signing the Contributor License Agreement. Let's get this merged! 🥳

@brophdawg11
Copy link
Contributor

@nicksrandall This is similar to #8567 - which was closed since the docs suggest a way to achieve this using existing hooks. Does that satisfy your use case?

@nicksrandall
Copy link
Author

Yes, that would work for me. IMO, NavLink should be refactored to use useMatch so things are consistent.

@hornta
Copy link

hornta commented Apr 7, 2022

Can't wait for this to get merged. Currently I'm using it to find out an active step in our multi-step form.

const steps: { name: string; to: To }[] = [
  { name: "Define the group structure", to: "." },
  { name: "Define the chart of accounts", to: "chart-of-accounts" },
  { name: "Define summary rows & KPI", to: "misc" },
  { name: "Set exchange strategies", to: "exchange" },
  { name: "Validate the data", to: "validation" },
];

const useActiveStep = () => {
  const matches: boolean[] = [];
  for (const step of steps) {
    // eslint-disable-next-line react-hooks/rules-of-hooks
    matches.push(usePathIsActive({ to: step.to, end: true }));
  }
  return matches.findIndex((match) => {
    return match !== false;
  });
};

@paul-sachs
Copy link

paul-sachs commented May 13, 2022

I'd like to get this merged since I have a link component that uses a prop instead of classname or style to determine active or not. This hook would easily allow more flexible versions of the NavLink.

#8567 doesn't really work, since NavLink can be a relative path, but useMatch doesn't seem to take into context the currently matched path. Unless I'm super missing something...

@brophdawg11
Copy link
Contributor

👋 Hey folks - I'm going to close this out for the same reasons discussed in #8567 - we think useResolvedPath/useMatch provides the necessary API for custom isActive logic and we are going to look into changing the internal implementation to use those hooks directly.

@hornta have you tried using the useResolvedPath/useMatch suggestion in #8567? If that's not sufficient, would you mind opening a new issue with a simple reproduction and we can look into it there?

@paul-sachs Would you also be able to open a new issue with a simple reproduction where that approach doesn't suffice for you? That way we can see if there are other options.

@paul-sachs
Copy link

paul-sachs commented May 16, 2022

@brophdawg11 turns out the reason my example wasn't working was due to a bug in userland. useResolvedPath and useMatch seem to provide everything I need. Would be nice to have a way to iterate over multiple paths but that's probably a different issue.

@brophdawg11
Copy link
Contributor

If you need to look for a match on something other than the current location you may be able to just use matchPath() directly. useMatch() is really just a tiny memoized wrapper around that + useLocation()

brophdawg11 pushed a commit that referenced this pull request Mar 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants