remix icon indicating copy to clipboard operation
remix copied to clipboard

Fetchers that throw redirects can cause infinite loops when actions also redirect

Open dmarkow opened this issue 2 years ago • 4 comments

What version of Remix are you using?

1.11.1

Are all your remix dependencies & dev-dependencies using the same version?

  • [X] Yes

Steps to Reproduce

https://github.com/dmarkow/remix-redirect-issue

  • Current page (/) loads data with useFetcher
  • The route that fetcher loads from (/data) can possibly redirect (in my case, to redirect to a login form if necessary)
  • Post to an action on that page that returns or throws a redirect (in this example, a log out button that clears the session and redirects to /login)
  • After that action completes, the loader for the next page (/login) starts running. But before the redirect actually happens, the fetcher on the previous page (/) reloads as well, triggering another redirect.
  • Infinite loop, and the next page never loads.

This started in 1.10.0 with the fetcher revalidation updates.

CleanShot 2023-01-25 at 11 45 17@2x

Expected Behavior

If a redirect is already being handled, additional redirects to the same destination should be ignored and not trigger fetcher revalidations.

Actual Behavior

Infinite loop.

dmarkow avatar Jan 25 '23 17:01 dmarkow

Can confirm this behavior exists now and didn't exist in 1.9. Curious why the fetcher.load is triggered after each thrown redirect? For me, the infinite loop happens after a logout, because fetcher.load gets triggered for some reason after logout, then it tries to authenticate the request -- which throws a redirect, which causes fetcher.load to get triggered for some reason, to infinity.

barbinbrad avatar Jan 25 '23 19:01 barbinbrad

@barbinbrad At least for this specific issue, 1.9.0 worked fine for me. 1.10.0 is where the issue started (when Remix fully switched to the new router).

dmarkow avatar Jan 25 '23 19:01 dmarkow

@barbinbrad At least for this specific issue, 1.9.0 worked fine for me. 1.10.0 is where the issue started (when Remix fully switched to the new router).

You're right. I just tested it. I had switched to ^1.9.0 which didn't actually resolve to 1.9.0 -- but a hard pin got rid of the problem.

barbinbrad avatar Jan 25 '23 19:01 barbinbrad

I tried playing with the shouldRevalidate function, but it didn't seem like it was getting called. For me the solution was to not throw a redirect in any route that was fetched from the client. Instead returning null from the session check and handling that case. Obviously, it's a crappy solution.

barbinbrad avatar Jan 25 '23 19:01 barbinbrad

Cleaning up my issues and it looks like this got resolved starting in 1.12.0 (probably the react-router update to 6.8.0).

dmarkow avatar Feb 21 '23 13:02 dmarkow