S
SolidJS12mo ago
CC8

Basic Router

Hey there I want to have a simple Router component that I can use. Problem I'm curently facing is that it doesn't rerender on path change.
import { createSignal, onCleanup } from 'solid-js'

import Home from '../pages/Home'
import Dashboard from '../pages/Dashboard'
import NotFound from '../pages/404'

export default function Router() {
const [path, setPath] = createSignal(window.location.pathname)

const checkPath = () => {
console.log('Checking path')
const currentPath = window.location.pathname
if (path() !== currentPath) {
setPath(currentPath)
}
}

window.addEventListener('popstate', checkPath)

onCleanup(() => {
window.removeEventListener('popstate', checkPath)
})

const navigate = (to) => {
history.pushState({}, '', to)
setPath(to)
console.log('Navigating to', path())
}

switch (path()) {
case '/':
return <Home />
case '/dashboard':
return <Dashboard />
default:
return (
<>
<button onClick={() => navigate('/')}>Home</button>
</>
)
}
}
import { createSignal, onCleanup } from 'solid-js'

import Home from '../pages/Home'
import Dashboard from '../pages/Dashboard'
import NotFound from '../pages/404'

export default function Router() {
const [path, setPath] = createSignal(window.location.pathname)

const checkPath = () => {
console.log('Checking path')
const currentPath = window.location.pathname
if (path() !== currentPath) {
setPath(currentPath)
}
}

window.addEventListener('popstate', checkPath)

onCleanup(() => {
window.removeEventListener('popstate', checkPath)
})

const navigate = (to) => {
history.pushState({}, '', to)
setPath(to)
console.log('Navigating to', path())
}

switch (path()) {
case '/':
return <Home />
case '/dashboard':
return <Dashboard />
default:
return (
<>
<button onClick={() => navigate('/')}>Home</button>
</>
)
}
}
8 Replies
Birk Skyum
Birk Skyum12mo ago
maybe the switch can be inside the jsx
Brendonovich
Brendonovich12mo ago
your switch isn't inside a reactive context, so it's only being ran once. put it in a createMemo or inside a jsx fragment
Birk Skyum
Birk Skyum12mo ago
@CC8 , your code would be fine in react, which reruns the entire component, and thus can have multiple return statements. In solid, the top part of the component (the setup) is only executed once, so it's only the first return statement that will be hit (the render function). That's why as bendonovich says, your control flow has to be either inside a reactive context made in the setup part (like memo), or inside the render function itself.
CC8
CC8OP12mo ago
so i should so something likethis ?
return (
<>
{(() => {
switch (path()) {
case '/':
return <Home />
case '/dashboard':
return <Dashboard />
default:
return (
<>
<button onClick={() => navigate('/')}>Home</button>
</>
)
}
})()}
</>
)
return (
<>
{(() => {
switch (path()) {
case '/':
return <Home />
case '/dashboard':
return <Dashboard />
default:
return (
<>
<button onClick={() => navigate('/')}>Home</button>
</>
)
}
})()}
</>
)
Birk Skyum
Birk Skyum12mo ago
either that, or something like this
const Page = createMemo(()=>{
switch (path()) {
case '/':
return <Home />
case '/dashboard':
return <Dashboard />
default:
return (
<>
<button onClick={() => navigate('/')}>Home</button>
</>
)
}
})

return <Page />
const Page = createMemo(()=>{
switch (path()) {
case '/':
return <Home />
case '/dashboard':
return <Dashboard />
default:
return (
<>
<button onClick={() => navigate('/')}>Home</button>
</>
)
}
})

return <Page />
CC8
CC8OP12mo ago
alright thanks fingerguns now do you know a way I can export the navigate function because I want to use it in other components without passing it through props
Birk Skyum
Birk Skyum12mo ago
I believe you can just move const [path, setPath] = createSignal(window.location.pathname) and

const navigate = (to) => {
history.pushState({}, '', to)
setPath(to)
console.log('Navigating to', path())
}

const navigate = (to) => {
history.pushState({}, '', to)
setPath(to)
console.log('Navigating to', path())
}
outside the component, and write export in front of them or in case the window.location.pathname is troublesome so it's only the navigate that's moved out, simply add the path and setpath signals to the argument list of navigate export const navigate = (to, path, setPath) => {...}
CC8
CC8OP12mo ago
upvote thanks for the help guys
Want results from more Discord servers?
Add your server