-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
Description
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:
react-router/packages/react-router/lib/hooks.tsx
Lines 173 to 175 in 5a1ca08
| 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.0Used 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.