Navbar re-renders

Other than with solidjs, with solid-start using the "A" Component my Navbar reloading every time i click on a Link. How can i avoid this behavior?
9 Replies
Martnart
Martnart15mo ago
I am assuming this is because you have async data that triggers the global suspense boundary. You can circumvent this by introducing a more localized Suspense that "catches" the resource.
<Navbar />
<Suspense>
<Outlet /> // Your main content
</Suspense>
<Navbar />
<Suspense>
<Outlet /> // Your main content
</Suspense>
matulla_ffm
matulla_ffm15mo ago
i don't really understand - at the moment it look like this. <Body> <Suspense> <ErrorBoundary> <Navbar active={active} /> <Routes> <FileRoutes /> </Routes> </ErrorBoundary> </Suspense> <Scripts /> </Body>
Martnart
Martnart15mo ago
In your example, if you want to keep your structure, just to try to change it like this
<Body>
<Suspense>
<ErrorBoundary>
<Navbar active={active} />
+ <Suspense>
<Routes>
<FileRoutes />
</Routes>
+ </Suspense>
</ErrorBoundary>
</Suspense>
<Scripts />
</Body>
<Body>
<Suspense>
<ErrorBoundary>
<Navbar active={active} />
+ <Suspense>
<Routes>
<FileRoutes />
</Routes>
+ </Suspense>
</ErrorBoundary>
</Suspense>
<Scripts />
</Body>
Suspense is basically a "Loader" that subscribes to async processes/resources. If you don't have any localized Suspense it will trigger the global suspense which will literally "suspend" the app for the time being and in this case basically rerender everything. By inserting a Suspense boundary closer to whatever triggers it, you can only suspend that part - meaning your Navbar will not rerender, only your content will change. Might be it's something else but this at least is a common reason for the problem you described.
matulla_ffm
matulla_ffm15mo ago
I tried this - same problem. Then i removed all async data fetching und every call to signals - i.e. no interactivity - same problem. Could this be the default behavior?
Unknown User
Unknown User14mo ago
Message Not Public
Sign In & Join Server To View
Martnart
Martnart14mo ago
It is not. I had prepared a bit of a showcase that shows the problem. This is only one possible source of the problem, though. It might also be related to having your navbar rerender due to it being inside a keyed show, e.g. To debug, need to see actual code. Anyway, here's a series for an example. 1. https://stackblitz.com/edit/solid-start-bare-ts-mwm1o7 Everything works fine. You have a navbar and you can navigate between pages without rerendering. 2. https://stackblitz.com/edit/solid-start-bare-ts-teuyd9 Introducing a dynamic resource breaks it, whenever the resource is fetching, app is suspended and rerenders navbar 3. https://stackblitz.com/edit/solid-start-bare-ts-hsjxu9 Wrapping the route's content in a Suspense keeps navbar static and only suspends main content
Unknown User
Unknown User14mo ago
Message Not Public
Sign In & Join Server To View
Martnart
Martnart14mo ago
I am not entirely sure how the structure of this looks like. Seeing that you use props.children suggests that you are using this snippet as a component. As such it would rerender if you remount a different instance of this component for each route. In this case you should indeed use <Outlet /> on a route level to have dynamic content in a layout. Or just put Navbar outside of your <FileRoutes /> component in root.tsx as OP did. Just for reference, I'll post a stripped-down version of how we deal with our Navbar in my current SolidStart project.
// (app).tsx
export default function ProtectedLayout() {

return (<>
<Sidebar />
<div class="flex h-full w-full flex-col lg:pl-64">
<Topnav />
<div class="mt-12 flex-1 opacity-100 transition-opacity data-[actionbar]:sm:pb-20">
<ErrorBoundary fallback={(e) => `Error: ${e.message}`}>
<Suspense>
<Outlet />
</Suspense>
</ErrorBoundary>
</div>
</div>
</>)
}
// (app).tsx
export default function ProtectedLayout() {

return (<>
<Sidebar />
<div class="flex h-full w-full flex-col lg:pl-64">
<Topnav />
<div class="mt-12 flex-1 opacity-100 transition-opacity data-[actionbar]:sm:pb-20">
<ErrorBoundary fallback={(e) => `Error: ${e.message}`}>
<Suspense>
<Outlet />
</Suspense>
</ErrorBoundary>
</div>
</div>
</>)
}
Any content routes then go into (app)/ folder
https://cinemascan-solidstart.vercel.app/
Is that your app? Looks pretty neat and I don't see any problem ?!
Unknown User
Unknown User14mo ago
Message Not Public
Sign In & Join Server To View