Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

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

useMatch's memo is easy to break by accident using a PathPattern #12978

Open
epmatsw opened this issue Feb 7, 2025 · 1 comment
Open

useMatch's memo is easy to break by accident using a PathPattern #12978

epmatsw opened this issue Feb 7, 2025 · 1 comment
Labels

Comments

@epmatsw
Copy link

epmatsw commented Feb 7, 2025

I'm using React Router as a...

library

Reproduction

I promise I tried to make a StackBlitz for this, but it really doesn't like demos that trigger infinite loops 😂

This is kind of a toy example, but if you pass a PathPattern object to useMatch, its memoization starts to fail. That's sneaky, because going from (working) code like this:

  const [count, setCount] = useState(0);
  const match = useMatch('test');
  useEffect(() => setCount((c) => c + 1), [match]);

to this:

  const [count, setCount] = useState(0);
  const match = useMatch({
    path: 'test',
    caseSensitive: true,
  });
  useEffect(() => setCount((c) => c + 1), [match]);

introduces an infinite loop.

I think that the memo here:

return React.useMemo(
() => matchPath<ParamKey, Path>(pattern, decodePath(pathname)),
[pathname, pattern]

could be tweaked a bit to pull the values off of the passed in object (if it's an object) instead of forcing each caller to add an additional useMemo to get memoization to work.

System Info

Binaries:
    Node: 23.7.0 - ~/.nvm/versions/node/v23.7.0/bin/node
    Yarn: 4.6.0 - /opt/homebrew/bin/yarn
    npm: 10.9.2 - ~/.nvm/versions/node/v23.7.0/bin/npm
    bun: 1.2.1 - ~/.bun/bin/bun
    Watchman: 2024.11.04.00 - /opt/homebrew/bin/watchman
  Browsers:
    Chrome Canary: 135.0.7003.0
    Safari Technology Preview: 18.0

Used Package Manager

npm

Expected Behavior

useMatch returns a memoized object when feasible.

Actual Behavior

When you pass in a PathPattern, useMatch's result is no longer memoized.

@epmatsw epmatsw added the bug label Feb 7, 2025
@epmatsw
Copy link
Author

epmatsw commented Feb 7, 2025

Memoization was added to this hook in #7059 and #8431

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant