-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Fetchers trigger unnecessary useLocation/LocationContext updates #3672
Comments
I reproduced the error by adding the route here a test repo https://github.com/wanbinkimoon/remix-use-fetcher-rerender-testing |
This is something i'm experiencing and its causing really slow client navigation. Here's my situation: I have a table of items that can be infinitely paginated. On this same page I have a few links to "modal routes". In each item component I have a few "useFetcher" hooks that are used to submit things to certain actions (duplicate, delete, archive etc). When opening any of the modal routes, the url updates, and I can see that the useFetcher hook is causing each item to re-render. This is causing the modal routes to render really slowly, >2seconds as remix/react is re-rendering every single one of the items. I don't get why the useFetcher hooks, which aren't dependent on the URL/location, need to cause these updates.
p.s because I use "useFetcher" all over the place, it causes so many things to re-render when they really dont need to so, I've had to put React.memo everywhere too to limit the damage and stop all children components re-rendering. But there's nothing I can really do about the component that uses the hook directly. Thoughts? |
Seems like this line is still causing the issue: https://github.com/remix-run/react-router/blob/main/packages/react-router/lib/components.tsx#L355 do the objects need to be memoized? |
remix-run/react-router#9983 was merged which should fix this when that release is published. |
What version of Remix are you using?
1.6.3
Steps to Reproduce
Sample component below. One child component calls a fetcher, the other child component calls useLocation. The location component renders 3 times total, even when using React.memo. However, the actual value of useLocation stays the same.
Expected Behavior
The useFetcher docs specifically say "Because useFetcher doesn't cause a navigation...". I would assume not causing navigation means that
useLocation()
shouldn't change.Actual Behavior
useLocation() causes unnecessary re-renders when using fetchers, which can be costly on large/complex pages.
Digging in, it seems that https://github.com/remix-run/react-router/blob/main/packages/react-router/lib/components.tsx#L235 may be the culprit? Even though
location
andnavigationType
aren't actually changing, it's creating a new object withvalue={{ location, navigationType }}
any time theRouter
component re-renders.I tested patching this to wrap the context value with
useMemo
and the re-renders stopped:I was unsure if this issue is Remix-specific with the fetchers causing unnecessary updates of
LocationContext
, of if this bug needs to be addressed in react-router instead?The text was updated successfully, but these errors were encountered: