添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account < Route path = "/" element = { < Root / > } > < Route index element = { < p > Index < / p > } / > < Route path = "user" element = { < p > User < / p > } / > < Route path = "user-preferences" element = { < p > User Preferences < / p > } / > < / Route > < / Routes > < / BrowserRouter >
  • Show NavLinks to the routes
    const Root = () => (
          <NavLink to="user">Go to /user</NavLink>
          <NavLink to="user-preferences">Go to /user-preferences</NavLink>
    
  • Navigate to /user-preferences path
  • Code Sandbox

    Expected Behavior

    The link to /user-preferences should have the active class and the link to /user should not have the active class. This is the behavior in [email protected]

    Actual Behavior

    Both links have the active class.

    What happens if you add end prop to your <NavLink>? It looks like it's matching on partial URL: basically isActive = path.startsWith('/user').

    Adding end does sort of workaround it, but it means that the child routes of /user no longer match. This worked without end in 6.3. My expectation is that isActive = useMatch('/user') != null.

    There's a test that checks that partial segments do not apply the active class. If I change the /children route to /child-ren the test fails in 6.4.0 and passes in 6.3.0.

    [Bug]: NavLink is active when useMatch is false (react-router-dom v6.4) [Bug]: NavLink is active for partial segment matches (react-router-dom v6.4) Sep 16, 2022

    Two updates, first I found why the useMatch() hook has a different result than the component. useMatch('/user') will default the unset end parameter to true, while useMatch({pathname: '/user'}) (what NavLink will effectively call) will default end to false

    My other finding is that I think the regression comes from this part of the regular expression defined in compilePath

    // Otherwise, match a word boundary or a proceeding /. The word boundary restricts
    // parent routes to matching only their own words and nothing more, e.g. parent
    // route "/home" should not match "/home2".
    // Additionally, allow paths starting with `.`, `-`, `~`, and url-encoded entities,
    // but do not consume the character in the matched path so they can match against
    // nested paths.
    "(?:(?=[@.~-]|%[0-9A-F]{2})|\\b|\\/|$)";

    Its treating - as a word boundary and therefore like as if /user-preferences is a child route of /user. It feels like the part that says allow paths starting with special characters, should mean only match if the path was something like /user/-preferences.

    NavLink in 6.3 didn't use useMatch and this regular expression.

    Hello mate,

    First, in this case, I suggest splitting the pathname "user-preferences" to "user/preferences" but another solution is to make a custom NavLink component.

    Like this:

    const CustomNavLink = ({ className, children, to }) => {
      const { pathname } = useLocation();
      const match = to === pathname.split('/').join('');
      return (
        <NavLink to={to} style={{color: match ? 'red': 'black'}} >
          {children}
        </NavLink>
              

    I looked into this briefly and I think this may be a previously undiscovered bug in matchPath that's now exposed more broadly since we changed NavLink to use it internally. We did this to better align its approach with our recommended approach for custom NavLink behavior in https://github.com/remix-run/react-router/blob/main/examples/custom-link/src/App.tsx.

    Going to chat with @mjackson to confirm since he wrote most of the original approach in matchPath.

  •