S
SolidJS•13mo ago
Mr Void

Why does `Outlet` not work when using `element` instead of `component` in the configuration?

Wrapper / container
const MainContainer = () => (
<div class="flex flex-row min-h-screen">
<Outlet />
</div>
)
const MainContainer = () => (
<div class="flex flex-row min-h-screen">
<Outlet />
</div>
)
This works:
const MainContainer = lazy(() => import("../mainContainer"))

const Dashboard = lazy(() => import("../../pages/dashboard"))

const Routes = useRoutes([
{
path: "/",
component: MainContainer,
children: [
{ path: "/dashboard", component: Dashboard }
]
}
])
const MainContainer = lazy(() => import("../mainContainer"))

const Dashboard = lazy(() => import("../../pages/dashboard"))

const Routes = useRoutes([
{
path: "/",
component: MainContainer,
children: [
{ path: "/dashboard", component: Dashboard }
]
}
])
This doesn't work:
const MainContainer = lazy(() => import("../mainContainer"))

const Dashboard = lazy(() => import("../../pages/dashboard"))

const Routes = useRoutes([
{
path: "/",
element: <MainContainer />,
children: [
{ path: "/dashboard", element: <Dashboard /> },
]
}
])
const MainContainer = lazy(() => import("../mainContainer"))

const Dashboard = lazy(() => import("../../pages/dashboard"))

const Routes = useRoutes([
{
path: "/",
element: <MainContainer />,
children: [
{ path: "/dashboard", element: <Dashboard /> },
]
}
])
8 Replies
lxsmnsyc
lxsmnsyc•13mo ago
it doesn't work because you're rendering the elements at the moment of declaration (remember, Solid has no VDOM) You can convert element into a getter
Mr Void
Mr VoidOP•13mo ago
I don't understand, an element gets rendered if it's a "parent" route but child routes don't get rendered. Why? What does it mean to convert an element into a getter? When should one choose element over component, in a route? ---- The goal I have is to have an component such as: <AllowAuthenticated accept={SomeComponent} /> that returns SomeComponent if user is authenticated, otherwise <Navigate /> to login. I was thinking about doing it like:
const Routes = useRoutes([
{
path: "/",
{/* Allow access to MainContainer ( and sub components ) - IF authenticated */}
element: <AllowAuthenticated accept={<MainContainer />} />,
children: [
{ path: "/dashboard", element: <Dashboard /> },
]
}
])
const Routes = useRoutes([
{
path: "/",
{/* Allow access to MainContainer ( and sub components ) - IF authenticated */}
element: <AllowAuthenticated accept={<MainContainer />} />,
children: [
{ path: "/dashboard", element: <Dashboard /> },
]
}
])
but that apparently isn't working thinkConfused element not rendered thinkConfused I am confused
lxsmnsyc
lxsmnsyc•13mo ago
function Example() {
console.log('rendered!');
}

// This element gets rendered the moment this variable is evaluated.
const example = <Example />;
function Example() {
console.log('rendered!');
}

// This element gets rendered the moment this variable is evaluated.
const example = <Example />;
in which case the same thing happens with element: <Example /> which is why you can solve this by doing:
get element() {
return <Example />;
}
get element() {
return <Example />;
}
or element: () => <Example /> also works (if you aren't using TS)
Mr Void
Mr VoidOP•13mo ago
Does having them imported through lazy not create getter for the elements?
lxsmnsyc
lxsmnsyc•13mo ago
lazy is irrelevant here as I'm talking about how elements in Solid behave
Mr Void
Mr VoidOP•13mo ago
I will try to think about this and see if I can get it to work thank you for helping <a:pepe_saber:1094297975141978214>
lxsmnsyc
lxsmnsyc•13mo ago
just follow this
Mr Void
Mr VoidOP•13mo ago
🫡 planning to wrap it in a function as you showed, I'll let you know if it namastedoge works as expected! 🎉 partyBlob thank you very much peposmile <a:pepe_saber:1094297975141978214> was going mad over this whygod
const allowAuthenticated = (accept: Component): JSX.Element => {
if (store.user.isAuthenticated) {
return accept({})
}

return <Navigate href={'/login'} />
}

const denyAuthenticated = (accept: Component): JSX.Element => {
if (!store.user.isAuthenticated) {
return accept({})
}

return <Navigate href={'/'} />
}

return (
<Routes>
<Route path="/" element={allowAuthenticated(MainContainer)}>
<Route path="/" component={Dashboard} />
</Route>
</Routes>
)
}
const allowAuthenticated = (accept: Component): JSX.Element => {
if (store.user.isAuthenticated) {
return accept({})
}

return <Navigate href={'/login'} />
}

const denyAuthenticated = (accept: Component): JSX.Element => {
if (!store.user.isAuthenticated) {
return accept({})
}

return <Navigate href={'/'} />
}

return (
<Routes>
<Route path="/" element={allowAuthenticated(MainContainer)}>
<Route path="/" component={Dashboard} />
</Route>
</Routes>
)
}
what does Component<void> change? think I see now, that way I would replace accept({}) with accept(), is that what you namastedoge thank you Toka
Want results from more Discord servers?
Add your server