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

Context is undefined after redirect #1531

Closed
maksymskuibida opened this issue Apr 29, 2024 · 42 comments · Fixed by #1599
Closed

Context is undefined after redirect #1531

maksymskuibida opened this issue Apr 29, 2024 · 42 comments · Fixed by #1599
Labels
information needed Further information is requested

Comments

@maksymskuibida
Copy link

Describe the bug

I use authentication, similar to Authenticated Routes example from documentation. So, when user is on /$lang page, if user is not authorised, user is been redirecting to /$lang/login page. It happens, but useRouteContext returns undefined instead of context. I set context in RouterProvider like this. If I reload the page, issue disappears

<RouterProvider
    router={router}
    context={{ auth, queryClient, showAppAlert }}
/>

I tested on 1.29.2, 1.30.1, 1.31.1, issue happens. I also tested on 1.26.21 and issue does not happen. I didn't test versions between 1.26.21 and 1.29.1

Your Example Website or App

https://admin.7loc.com/en

Steps to Reproduce the Bug or Issue

It happens in our live admin panel(admin panel at all is in development, but some functionality have already been implemented)

Expected behavior

Context, if it set in router provider is always available and not undefined

Screenshots or Videos

undefined.context.issue.mov

Platform

  • Version: 1.29.2-1.31.1

Additional context

No response

@maksymskuibida
Copy link
Author

maksymskuibida commented Apr 29, 2024

UPDATE.

It happens if I redirect from /$lang to /$lang/login. If I redirect from / to /$lang/login it does not happen. Also attached error, that appears in console
image

undefined.context.issue.2.mov

@SeanCassiere
Copy link
Contributor

Redirects were broken between 1.28.2 and 1.31.1, but on the side of the Router context, nothing has changed in that area in a LONG time.

We'd need a working reproduction for us to be able to diagnose what specifically in your setup is breaking stuff for you.

Also please confirm this issue you are facing on version 1.31.3 as well.

You can create a reproduction using the Router file-based stackblitz starter.

@SeanCassiere SeanCassiere added the information needed Further information is requested label Apr 29, 2024
@SeanCassiere
Copy link
Contributor

SeanCassiere commented Apr 30, 2024

I tried to reproduce this and wasn't able to recreate this on my end with version 1.31.3.

Here's my attempt: https://stackblitz.com/edit/github-dxj2gr

@mwood23
Copy link

mwood23 commented Apr 30, 2024

@SeanCassiere Managed to repro: https://stackblitz.com/edit/github-dxj2gr-btjqhp

@SeanCassiere SeanCassiere added bug Something isn't working and removed information needed Further information is requested labels Apr 30, 2024
@mintaka2479
Copy link

I am having the same issue

https://stackblitz.com/edit/github-dxj2gr-xfuqc1

Case 1

  1. Access /about from the address bar of your browser
  2. Redirect to /foo
  3. Cannot read properties of undefined (reading 'fn') is displayed

Case 2

  1. Added defaultGcTime: 0 to createRouter options
  2. Access Try me! from Home
  3. Cannot read properties of undefined (reading 'fn') is displayed

@maksymskuibida
Copy link
Author

@mintaka2479 By any change, do you have any workaround for this issue? Because it brokes login/logout on my website. Now after login and logout I have this issue and user has to reload the page to fix it

@budde377
Copy link

budde377 commented May 1, 2024

Downgrading to 1.26.21 fixed the issue for us.

@maksymskuibida
Copy link
Author

Sometimes it also happens with loaderData

@jakst
Copy link

jakst commented May 2, 2024

Sometimes it also happens with loaderData

For us, loaderData was fixed in 1.31.6. Context is still sometimes undefined though.

@maksymskuibida
Copy link
Author

I am on the latest version and contextI can reproduce in one place every time, but one time in console I see error with both content and loader data on latest version, but I don't know, may be something else caused it, because it was only one time on new version. As I use query, now I almost don't use loaderData, so, I cannot say more about it. But context issue is still happening and cause serious problems. As we still develop our app it is not a critical problem, but I hope it will be fixed soon

@ccapndave
Copy link
Contributor

I am experiencing this too - when redirecting from one route to another in beforeLoad, the context becomes undefined in the target route. It was introduced in v1.31.2.

@SeanCassiere
Copy link
Contributor

Please recheck this.

It's possible that this was inadvertently fixed with #1559.

@SeanCassiere SeanCassiere added information needed Further information is requested and removed bug Something isn't working labels May 4, 2024
@MAST1999
Copy link
Contributor

MAST1999 commented May 4, 2024

I'm still facing this problem.

If I redirect the context becomes undefined.

I'm on router version ^1.31.19.

@maksymskuibida
Copy link
Author

@SeanCassiere I have just tested on latest version and I am still facing this problem too

@mintaka2479
Copy link

The default options have been fixed.
However, if gcTime is 0, the loader’s context becomes undefined after the redirect.
There is no problem with beforeLoad.

https://stackblitz.com/edit/github-dxj2gr-xfuqc1

  1. Access Try me! from Home.

console log

1./foo.beforeLoad context {foo: 'bar', fn: ƒ}
2./foo.beforeLoad context.fn
3./foo.loader context undefined

@maksymskuibida
Copy link
Author

I don't have gcTime: 0. I have logout button. When user press on it, I remove auth token and make router.invalidate(), which causes throw redirect to login page in beforeLoad and in this moment context becomes undefined

@maksymskuibida
Copy link
Author

maksymskuibida commented May 4, 2024

I have just tested one more time. Issue happening only if I do throw redirect(). In logic logic I have two options.

  1. Url to redirect is specified in query param, in this case I do router.history.push()
  2. Url is not specified, in this case after logic I do throw redirect() to home page

So, when I do router.history.push it works. If I do throw redirect(), I am facing undefined context issue, nothing changed for me with the latest version

Issue also happens without router.invalidate() and etc. If I just go to home page anauthorised, what causes throw redirect() in my logic, it brakes with undefined context(video is from production build, in local build it shows like on screenshot)

https://github.com/TanStack/router/assets/57814533/9bb4eacc-e4aa-4a3e-9752-874620ae9182
image

@SeanCassiere SeanCassiere added bug Something isn't working and removed information needed Further information is requested labels May 5, 2024
@ccapndave
Copy link
Contributor

I can also confirm that this is not fixed for me.

@freshgiammi
Copy link
Contributor

freshgiammi commented May 6, 2024

I've tried taking a stab at it since I've been facing this issue for a bit as well, but I'm hitting a wall. My issue is a bit different from the ones shared in the reproductions (can't share my code, and I haven't managed yet to create a repro), but basically context within loader (not beforeLoad, it's available there) is undefined after a redirect.
My routes are like this:

- __root
- __root/_auth
- __root/_auth/_page (Layout shell)
- __root/_auth/_page/ (Index page)
- __root/_auth/_page/unauthorized (Page that redirects the user to Index)

The unauthorized page redirects users from within a beforeLoad to the index page, but that causes the context in the index's loader to be undefined.
What I've seen is that once a redirect is executed, the first three routes are cached and retrieved from the Router's store, the and the unauthorized page is swapped with the index page with an empty context (since they both share the same parent tree).
Now, apparently all routes are created with no context (here) and get their context from here, however the newly matched route (Index, where the user is being redirected) doesn't reach that code block and consistently halts after executing https://github.com/TanStack/router/blob/main/packages/react-router/src/router.ts#L1563.
It looks like the flow just gets interrupted after the beforeLoad is executed, with the Router then failing here as no context can be provided to the loader for the last route matched (because it never gets to merge the context with the matched route).

I'll try making a repro again, but in the meanwhile I hope this can help pinpoint the issue somehow 🤷‍♂️

@maksymskuibida
Copy link
Author

@SeanCassiere By any change, do you know when will this be fixed approximately? It really makes a lot of problems in my app and, unfortunately, I cannot rollback to previous version, because there are other bugs there.
Thank you a lot for your work

@SeanCassiere
Copy link
Contributor

SeanCassiere commented May 7, 2024

I don't have the bandwidth to look into this until probably mid next week.

@tannerlinsley any idea around where this bug would be happening?

@bouchardm
Copy link

In the meantime here is a workaround

export const Route = createFileRoute('/a-route/')({
  component: () => {
  const navigate = useNavigate();

  setTimeout(() => {
    navigate({ to: '/another-route' });
  }, 0);

  return null;
}
})

ugly but working on my side

@Patchrik
Copy link

I tested replacing throw redirect({}) with router.navigate() and now issue does not appear. So, issue appear only with throw redirect(). I event don't need setTimeout, it works without it( I do it in beforeLoad, not in component, so hook is not available )

This also worked for me, and I'm on v1.32.2

@ccapndave
Copy link
Contributor

ccapndave commented May 15, 2024

Yup, this workaround does the job 👍

One thing to be careful of is to include { replace: true } in the options to navigate, otherwise it will put the route onto the stack and probably break the back button.

@KirillTregubov
Copy link

I can confirm I am running into the same issue and the culprit seems to be throw redirect().

My reproduction: https://stackblitz.com/edit/github-xhruej?file=src%2Froutes%2Fabout.tsx,src%2Froutes%2Findex.tsx&file=src%2Froutes%2Fabout.tsx

Steps to Reproduce the Bug or Issue

  1. Open the DevTools console.
  2. Notice you are on the About page. If you look in the console, you were redirected on initial load.
  3. Press the "Navigate" button.
  4. Notice you are on the Index page. If you look in the console, you will see that the loader context is undefined.

Expected behavior

  1. Open the DevTools console.
  2. Notice you are on the About page. If you look in the console, you were redirected on initial load.
  3. Press the "Navigate" button.
  4. Notice you are on the Index page. If you look in the console, the loader context is an object containing the queryClient

After navigating to a page that has been redirected from, the loader context should not be undefined. We are suggested by the docs / examples to use loader: ({ context: { queryClient }) => {} when defining loaders, which is not valid if context can be undefined.

@freshgiammi
Copy link
Contributor

freshgiammi commented May 15, 2024

I can confirm I am running into the same issue and the culprit seems to be throw redirect().

My reproduction: https://stackblitz.com/edit/github-xhruej?file=src%2Froutes%2Fabout.tsx,src%2Froutes%2Findex.tsx&file=src%2Froutes%2Fabout.tsx

I didn't have time to make a reproduction but this is exactly what I said I'm facing in #1531 (comment).

An error is thrown here on the offending route (in this case, /),and then the cached match in the router store gets updated (here). However, the route remains in a pending state because the finally statement overrides this by using the scoped match object. On the next iteration, it is then skipped as it's marked with isFetching: true.

Moving the updateMatch call from the finally block to the end of the try block fixes this context issue for me, and so does reverting this commit which was introduced in 1.28.6.

cc @SeanCassiere I don't know what that commit was supposed to fix, so I haven't made a PR reverting it but I'm happy to if needed 👍

@SeanCassiere
Copy link
Contributor

Moving the updateMatch call from the finally block to the end of the try block fixes this context issue for me...

@freshgiammi this seems to do the trick.

@SeanCassiere
Copy link
Contributor

SeanCassiere commented May 16, 2024

This should now be fixed with the 1.32.11 release.

📢 Huge shoutout to @freshgiammi for the fix.

@ccapndave
Copy link
Contributor

I'm so sorry to say this, but it still doesn't work for me with 1.32.11 :( This is the bug from hell, eh?

@SeanCassiere SeanCassiere reopened this May 16, 2024
@SeanCassiere
Copy link
Contributor

SeanCassiere commented May 16, 2024

I'm so sorry to say this, but it still doesn't work for me with 1.32.11 :( This is the bug from hell, eh?

@ccapndave a minimal reproduction will be needed for this to be looked into. You can create a minimal reproduction using the Router file-based stackblitz starter or Router code-based stackblitz starter. Please make sure your reproduction uses a minimum version of 1.32.11.

Edit: I'll keep this open for a few days for anyone else who is still running into a problem matching this issue's description.

@SeanCassiere SeanCassiere added information needed Further information is requested and removed bug Something isn't working labels May 16, 2024
@KirillTregubov
Copy link

This should now be fixed with the 1.32.11 release.

📢 Huge shoutout to @freshgiammi for the fix.

1.32.11 fixes my issue/reproduction. Cheers!

@callumbooth
Copy link

callumbooth commented May 16, 2024

Unfortunately this isn't working for me in 1.32.11.

I've managed to create a repro in stackblitz: https://stackblitz.com/edit/github-kx4dql-mgkaub?file=src%2Froutes%2Fabout.tsx

I think I've narrowed it down to something related to <StrictMode>.

Repro steps:

  1. Go to the repo link above and open the preview.
  2. Go to the about page and open browser dev tools console
  3. In the browser url, remove the search params, so just /about
  4. See that url bar has changed and the we do not receive any context in the loader.
  5. Reload the page, see that when the url has the search param we don't redirect and do get the context in the loader

Now if you remove StrictMode and retest the issue doesn't happen.

@SeanCassiere SeanCassiere added bug Something isn't working and removed information needed Further information is requested labels May 17, 2024
@SeanCassiere
Copy link
Contributor

Now if you remove StrictMode and retest the issue doesn't happen.

That's certainly a weird one. I'm currently having trouble replicating this in a unit test.

I'll have to leave this open until I get more bandwidth to get back to this.

@maksymskuibida
Copy link
Author

It is still not fixed for me. I tested on the latest version at issue still persists. I don't sure was it like that before or not,but, I checked in react router devtools and context is undefined in latest route match. In __root and $lang routes context is not undefined, but in $lang.login it is undefined

2024-05-17.17.19.01.mov

@maksymskuibida
Copy link
Author

And, again,
image

replacing throw redirect() with router.navigate fixes the issue

@freshgiammi
Copy link
Contributor

Yeah, it looks like this issue might have been fixed only in part.
With this reproduction template from this comment (with the packages updated accordingly here) I do see issue 2, while issue 1 has been fixed.

Looks like this time it's this function throwing an error, which halts the flow and skips the context assignment to the matched route.

I won't have time to dig deeper until next week so I'm dropping this here in case anyone wants to look into this issue 👋

@cpakken
Copy link

cpakken commented May 18, 2024

I made a reproduction:
https://github.com/cpakken/issue-tanstack-router-layout-route-context
#1618
Seems like it only affects _layout routes for me on non-initial loads. The context appears in child routes of _layouts and root

@SeanCassiere
Copy link
Contributor

The gcTime problem has been fixed with 1.32.15.

@SeanCassiere
Copy link
Contributor

Now if you remove StrictMode and retest the issue doesn't happen.

@callumbooth this problem has been fixed with the 1.32.16 release.

@maksymskuibida please retest with 1.32.16 using throw redirect() instead of navigate. If this doesn't work for you, we'll need a fresh minimal reproduction of your setup (without any unnecessary setup like auth, components, logging, etc.).

@cpakken Your issue will tracked separately in #1618. This issue is already a bit too crowded.

@SeanCassiere SeanCassiere added information needed Further information is requested and removed bug Something isn't working labels May 18, 2024
@maksymskuibida
Copy link
Author

@SeanCassiere I've just tested and I can confirm that it is fixed for me now. throw redirect() redirects correctly and there is no undefined context anymore.
Thank everyone who was involved for their work!

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

Successfully merging a pull request may close this issue.