react-router
react-router copied to clipboard
useFetcher and fetcher.submit in child component trigger unexpected parent (route) component re-render
Reproduction
Go to https://stackblitz.com/~/github.com/fonzcastellanos/react-router-use-fetcher-bug, enter a non-empty string to the "Message" input field, and press the "Submit" button.
Note that StrictMode is disabled.
System Info
System:
OS: macOS 15.5
CPU: (14) arm64 Apple M3 Max
Memory: 1.61 GB / 36.00 GB
Shell: 5.2.21 - /opt/homebrew/bin/bash
Binaries:
Node: 20.9.0 - ~/.nvm/versions/node/v20.9.0/bin/node
npm: 10.1.0 - ~/.nvm/versions/node/v20.9.0/bin/npm
npmPackages:
@react-router/dev: ^7.5.3 => 7.6.3
@react-router/node: ^7.5.3 => 7.6.3
@react-router/serve: ^7.5.3 => 7.6.3
react-router: ^7.5.3 => 7.6.3
vite: ^6.3.3 => 6.3.5
Used Package Manager
npm
Expected Behavior
I expected the Parent route component to not re-render, while the Child component would re-render as a result of calling fetcher.submit, which submits to the /resource resource route that defines only an action.
Actual Behavior
The Parent route component re-rendered unexpectedly. After the handlerSubmit function executed (which calls fetcher.submit), both the Parent and Child components re-rendered.
This is the browser console output.
This is the terminal output from the dev server. "hello world" was the string I entered into the "Message" field.
The following issue may be the same: https://github.com/remix-run/react-router/issues/13851
Are there any updates on that? We are facing similar issues with fetcher.load() in a polling component (causing the entire page/route to re-render).
I'm also wondering if there are any updates or next steps for this open issue? I'm also facing the same issue while using fetcher.load(...) in a child component of a page.
I was also under the impression that exporting a shouldRevalidate from an action should prevent this. But that doesn't work. Our use case is sending exposures for A/B tests which should be 'fire and forget', we have no need for refetching the current route.data.
As someone coming to this project I am finding this very confounding. Reading the docs I was under the impression that I could create a resource route (one that only exports an action) and use a fetcher interact with it from a child component. My use case is isolated pieces of UI within the parent page. Something like the ability to create tags or folders while I am editing a document. I don't want the document (the current route) to reload because I called a fetcher somewhere deep in the component stack. I guess server actions would be the way to go, but they are not advertised as stable. Else I can only think that I need to create express routes etc.. which not having to do that was what made Framework Mode so attractive in the first place. I wish there was a way to create components which have there own (server/client)loaders, and (server/client) actions and are decoupled from the URL and parent route.