vuejs / router

🚦 The official router for Vue.js
https://router.vuejs.org/
MIT License
3.91k stars 1.19k forks source link

Route changes state before unmounting the previous component #2018

Closed matijakevic closed 1 year ago

matijakevic commented 1 year ago

Reproduction

https://stackblitz.com/edit/vitejs-vite-rbabc7?file=src%2FApp.vue

Steps to reproduce the bug

  1. Click on Page A.
  2. Note that current tab on Page A is "tab 1" and that meta.title says "Component A".
  3. Click on Page B.
  4. Note that, while loading Page B, current tab on Page A is unknown (empty) and that meta.title says "Component B".

Expected behavior

Route state is retained for Page A until unmounted/loaded other route.

Actual behavior

Route state changes for Page A before unmounting/loading other route resulting in discrepancy (route params becoming empty, meta changing to other route's meta etc.)

Additional information

No response

posva commented 1 year ago

Unfortunately this is inherent to how suspense still renders and updates the previous node while awaiting the new node which happens only once the navigation has finished which is why you see the other meta property To address this, I started https://github.com/vuejs/rfcs/discussions/460 and feedback is more than welcome!

matijakevic commented 1 year ago

@posva Thank you for the reply!

While I like your proposal, it would still be nice if this behavior was somehow corrected without users depending on additional functionalities. Correct me if I'm wrong, but data loaders RFC seems orthogonal to fixing this behavior - they can exist with or without this fix.

You probably have more insight into this - is there any way to actually fix this? Would having two components mounted during load be sufficient solution? With one component having "old" route and the loaded one having "newer" route. This is contradictory to what I requested, but could fix the issues above.

posva commented 1 year ago

Would having two components mounted during load be sufficient solution?

Supporting Suspense + RouterView is something I have explored in the past. It's not enough. You can check Nuxt source code to create your custom RouterView and see a working version but it gets quite complex to workaround all the edge cases and still have issues (you can check existing issues in Nuxt).

The current direction is more towards data loaders as they don't create edge cases because they integrate within the navigation flow rather than the component mounting flow. This is crucial because both are decoupled.