remix-run / react-router

Declarative routing for React
https://reactrouter.com
MIT License
52.92k stars 10.25k forks source link

[Bug]: useLoaderData returns undefined when animating page transitions #12028

Closed asbjorn-brevio closed 1 week ago

asbjorn-brevio commented 2 weeks ago

What version of React Router are you using?

6.26.2

Steps to Reproduce

Open this code sandbox. Click the "About" link. An error overlay should be displayed, indicating that useLoaderData has returned undefined.

Expected Behavior

Since you have an example of animated page transitions (here), it appears that this is a use case you want to support. Therefore I would expect the "Home" page to be animated out, followed by an animation revealing the "About" page.

Actual Behavior

The page crashes because useLoaderData doesn't return anything for the route that's being animated out. Of course, I could make it not crash by not rendering elements that depend on loader data, but in many real world cases that could be a majority of the page content, which could make for some very janky and unpleasant transitions.

brophdawg11 commented 1 week ago

I'm not super familiar with the internals of framer motion but I think this is a limitation of their API in that it only captures props for the exit animations - but cannot "hold onto" old React Context values during an exit animation (related: https://stackoverflow.com/questions/67893190/why-does-using-react-context-with-framer-motion-not-work).

RouterProvider uses a React context internally to provide router data such as loader data down to components, so it makes sense that once the route is gone and the new route is rendered, the old index loader data wouldn't be around via context anymore.

I think in your case you may need to provide the relevant data down as props. Here's a simplified example of a pseudo-router showing the difference in data from context versus props: https://codesandbox.io/p/sandbox/damp-darkness-clvcyx?workspaceId=4591e983-08e5-4fcf-b73d-7ac4d03c4b11

One alternative might be using native view transitions via <Link>?

asbjorn-brevio commented 6 days ago

First of all, thanks for the thoughtful response and workarounds!

That said, I do feel like there's something unresolved here. The point of this report wasn't so much to find a way to solve my problem; it was more about highlighting the fact that from your github it appears as though this is supported, but it is in fact not. See f ex this discussion: https://github.com/remix-run/react-router/discussions/10823 and the previously mentioned example in your examples folder.

I think the fact that you have an example of how to add page transitions with the data router is slightly misleading. Yes, the example you provide does work, but only because the example happens to avoid loaders. If that example is applied to real world applications it's very likely that those applications will crash.

Knowing upfront whether page transitions is fully supported or not could be very relevant to someone who are contemplating whether to migrate their app to the data router API or not!

brophdawg11 commented 6 days ago

I'm on board with updating the example to show how it would need to work when loaders are introduced. Would you have any interest in taking a stab at that?

asbjorn-brevio commented 6 days ago

I would, but I'm a bit lost on how to tweak the current example to work though. I don't think any of the transition libraries would work because I suspect that they all rely on keeping a reference to children in state while they are animating them out (which is causing the issue).

View transitions look promising, but configuring this at the link level is quite the departure from configuring it at the router or route level (as in the current example). So that would probably be a separate example