S
SolidJS14mo ago
Revxrsal

solid-router not updating when going the same page but with different parameters

o/ so i have this in /routines/[id].tsx:
export default function EditRoutine() {
const params = useParams();
const routineIndex = storage.routines.findIndex(s => s.id == params.id)!;
const [routine, setRoutine] = createStore(
storage.routines[routineIndex]
)
return <RoutineForm
routine={routine}
setRoutine={setRoutine}
replace={true}
onFinish={(routine) => {
setStorage("routines", produce((r) => r[routineIndex] = routine))
}}
/>
}
export default function EditRoutine() {
const params = useParams();
const routineIndex = storage.routines.findIndex(s => s.id == params.id)!;
const [routine, setRoutine] = createStore(
storage.routines[routineIndex]
)
return <RoutineForm
routine={routine}
setRoutine={setRoutine}
replace={true}
onFinish={(routine) => {
setStorage("routines", produce((r) => r[routineIndex] = routine))
}}
/>
}
for some reason switching between two different pages of the same route (e.g. /id/1 and /id/2) doesn't change the routine and setRoutine. am i doing something wrong? (notice the address changing but the content remaining)
6 Replies
Revxrsal
Revxrsal14mo ago
note: storage is a store that itself contains a routines array, routine is an object that contains a string "id"
Tommypop
Tommypop14mo ago
You'll want to access params.id in an effect and update the store within that effect Otherwise it won't be reactive
Revxrsal
Revxrsal14mo ago
i did that, but i started getting weird behavior where if i click on the first routine, then the second routine, the first routine becomes a clone of the second routine i tried a hacky way, changed the routine and setRoutine to be a let instead of const, then update their values directly inside an effect. this made switching pages not affect the data at all. so i went further and put the Store<Routine> and SetStoreFunction<Routine> inside a signal, and that worked confusednick the updated code that works:
export default function EditRoutine() {
const params = useParams();
const routineIndex = () => storage.routines.findIndex(s => s.id == params.id)!;
const [routine, setRoutineSignal] = createSignal<Store<Routine>>()
const [setRoutine, setSetRoutine] = createSignal<SetStoreFunction<Routine>>()
createRenderEffect(() => {
const [store, setStore] = createStore(storage.routines[routineIndex()])
setRoutineSignal(store)
setSetRoutine(() => setStore)
})
return <RoutineForm
routine={routine()!}
setRoutine={setRoutine()!}
replace={true}
onFinish={(routine) => {
setStorage("routines", produce((r) => r[routineIndex()] = routine))
}}
/>
}
export default function EditRoutine() {
const params = useParams();
const routineIndex = () => storage.routines.findIndex(s => s.id == params.id)!;
const [routine, setRoutineSignal] = createSignal<Store<Routine>>()
const [setRoutine, setSetRoutine] = createSignal<SetStoreFunction<Routine>>()
createRenderEffect(() => {
const [store, setStore] = createStore(storage.routines[routineIndex()])
setRoutineSignal(store)
setSetRoutine(() => setStore)
})
return <RoutineForm
routine={routine()!}
setRoutine={setRoutine()!}
replace={true}
onFinish={(routine) => {
setStorage("routines", produce((r) => r[routineIndex()] = routine))
}}
/>
}
there are probably many things wrong with that, but i'd hope there's a better approach
REEEEE
REEEEE14mo ago
You probably want to make a copy of the routine data when you set it
export default function EditRoutine() {
const params = useParams();
const routineIndex = () => storage.routines.findIndex(s => s.id == params.id)!;
const [routine, setRoutine] = createStore(
storage.routines[routineIndex()]
)

createEffect(on(routineIndex, () => {
setRoutine(structuredClone(storage.routines[routineIndex()]))
}))


return <RoutineForm
routine={routine}
setRoutine={setRoutine}
replace={true}
onFinish={(routine) => {
setStorage("routines", produce((r) => r[routineIndex] = routine))
}}
/>
}
export default function EditRoutine() {
const params = useParams();
const routineIndex = () => storage.routines.findIndex(s => s.id == params.id)!;
const [routine, setRoutine] = createStore(
storage.routines[routineIndex()]
)

createEffect(on(routineIndex, () => {
setRoutine(structuredClone(storage.routines[routineIndex()]))
}))


return <RoutineForm
routine={routine}
setRoutine={setRoutine}
replace={true}
onFinish={(routine) => {
setStorage("routines", produce((r) => r[routineIndex] = routine))
}}
/>
}
Revxrsal
Revxrsal14mo ago
yeah sadly thoughg routines contain lots of functions and things unsupported by structured cloning but what's on?
REEEEE
REEEEE14mo ago
on is a way to explicitly set the dependencies for the effect. https://www.solidjs.com/docs/latest/api#on if it's not too nested, you could perhaps just {...routineData}
Want results from more Discord servers?
Add your server