Open illiaChaban opened 1 year ago
This sort of approach works for now but it is less than ideal since offscreen stuff is "live". I don't think we could make that a general solution. But I have an idea of how to do an "Offscreen" mechanism for the future.
For now I ended up with this:
function once(fn: Function, onAccess?) {
let acc = () => {
const { toReturn, target } = fn!()
onAccess?.(target)
acc = () => {
onAccess?.(target)
return toReturn
}
return toReturn
}
return () => acc()
}
function persist(Comp: Component) {
let routerRoot = document.body
const [node, setNode] = createSignal<HTMLElement>(null)
let rendered = false
function onAccess(val) {
// Init component
// This is needed to trigger it hooks
let output = val()
let i = 0
while (output?.constructor === Function) {
if (i > 10) throw new Error("Something bad happened in routing!")
output = output()
i++
}
if (output) setNode(output)
}
createEffect(() => {
const n = node()
if (!n || !routerRoot) return
if (!rendered) {
console.log(n, routerRoot.firstChild)
routerRoot.insertBefore(n, routerRoot.firstChild ?? null)
rendered = true
}
n.style.visibility = "unset"
})
function onWrapperShouldUnmount() {
const n = node()
if (!n) return
n.style.visibility = "hidden"
setNode(null)
}
const FakeComponent = () => {
const comp = <Comp ref={setNode} />
const target = () => {
onCleanup(onWrapperShouldUnmount)
return comp
}
return { toReturn: null, target }
}
return once(FakeComponent, onAccess)
}
Hi @ryansolid , is there any progress on this, or an alternative solution or pattern? I think this is a valuable feature. Vue has a built-in component for this: keep-alive.
The use-case I have is: we're building a dashboard SPA using Solidjs (btw: best decision we've ever made 😉 ... such a wonderful DX)... we have a page/route where the user can generate reports... they navigate to a different page/module, and when they go back to the report page, everything is cleared, so they have to setup all the filters again and rebuild the reports. This is obviously a bad UX, and the solution other libraries/frameworks offer is something like Vue's <keep-alive>
component.
I'd be really nice if Solidjs (or Solid-router?) had a similar feature, or at least, a documented pattern to achieve the same.
Keep on the good work Ryan. Solidjs is the best fvck$ng thing ever happened to the frontend universe, and I tell you so being myself an experienced Vue (2&3) and React developer.
Could you possibly store the data for the filter/report page globally so it persists independent of the router? Perhaps even in local storage if you want it to persist across page refreshes.
Or if that is not appropriate then use a nested(parent) route to store the data (and provide via context) so it persists for as long as the user is within a subsection of the router tree. We use this approach when we have a pair of list and detail pages and we want to keep the list data around while the user is in the detail page.
@erodriguezds keep-alive is a pretty difficult to make the way Solid works today as I was mentioning above. Vue's keep-alive does disconnect side effects and we don't have the means to do this before Solid 2.0. I didn't go out and say it in my response but that was where my idea for "Offscreen" for the future lies.
Describe the bug
Not a bug, but no templates for feature requests.
I want to be able to avoid rerendering a previously visited route and the route should keep all the internal state.
"persist?: boolean" prop would be nice Syntax proposal:
The way I accomplish it right now:
Your Example Website or App
https://github.com/solidjs/solid-router
Steps to Reproduce the Bug or Issue
None
Expected behavior
When has "persist" prop it should mount the component on first visit and not cleanup on navigate out
Screenshots or Videos
No response
Platform
all
Additional context
No response