[Bug report] Components being wrongly called
Closed this issue · 4 comments
Issue description
When using qwik-speak
, if we declare a routeLoader$
in the layout.txt file and re-use it across multiple routes, if we navigate through out some pages, both the from and the next component is called.
For example, if we navigate from "Home" to "Page", both the "Home" and "Page" components are called.
This appears to only happen when using qwik-speak
and only if routeLoader$
is declared in the layouts.txt. If we declare the routeLoader$
in each route, then the problem does not happen.
I took the opportunity to create a minimal reproduction branch with this problem (currently rebased with master): https://github.com/nelsonprsousa/qwik-speak/tree/min-rep-multiple-comp-calls
Also, please note that, based on my research:
- this problem does not happen without the use of qwik-speak;
- as a workaround, we can declare the
routeLoader$
in each route instead of layout.txt. The cons is that we need to duplicate the loader declaration in each route.
Steps to reproduce the issue
- Clone the repo
- Checkout branch min-rep-multiple-comp-calls
- yarn && yarn start
- Open site and your developer tools
- Navigate from Home to Page
- Check 2 logs, one from Home component and another one from Page component
What's the expected result?
- While navigating from Home to Page, only the Page component should be called.
What's the actual result?
- Both Home and Page components get called while navigating from Home to Page (SPA).
Additional details / screenshot
Here's what is happening when we navigate from Home
to Page
. The Home
component is not expected to be called. However, we get both logs, meaning that while navigating from home to page, the home component gets called for some reason.
For reference, here's a discord thread discussion regarding this problem: https://discord.com/channels/842438759945601056/1172197695172128798/1172205507457601626
In the meantime, all new findings regarding this problem should be added here in this issue report.
@nelsonprsousa Thanks for this detailed issue. Thanks to your reproduction I was able to isolate the problem.
You are importing the signal produced by routeLoader$
into the Home
and Page
components from layout (which is executed at each navigation). The problem is that these components are included in the Speak
component, and the Speak
component is a Slot
component: so it means that everything inside it is isolated, and recalled if something changes (like the routeLoader$
signal).
If you move const pageContextSignal = usePageContextLoader();
in the default component of the pages it works without recalling the component.
I think this is Qwik behavior by design.
The only way this library can avoid this, is to give up the Speak
component, and provide a hook for scoped translations, like:
export default component$(() => {
useSpeak({assets: ['home']});
return <Home />;
});
Pros:
- Avoid problems like in this issue
No need to create a nested (Home, Page) component for each page
Cons:
- That wouldn't be a jsx way
- It would be a breaking change
I will make other evaluations (opinions are welcome), and I will decide what to do.
Thanks for your detailed reply as well.
As a work around I am declaring the routeLoader$
in each individual route (I left the const declared but commented in the minimal reproduction branch).
I am not able to provide useful feedback regarding the solution you suggested since I am yet learning all the Qwik concepts, but I trust your judgment.
Thank you
I'm closing this issue, since from v0.17.0 Speak
(slot) component no longer exists, in favor of useSpeak
hook.
Greetings