How to unmount?
React has unmountComponentAtNode, preact has render(null, element), etc.
How would that work in Superfine?
patch(null, null, container) // ?
// or
unmount(container) //?
What is it expected from this operation?
Since the view/components are stateless, my best guess would be maybe calling the lifecycle events for onremove and ondestroy? Assuming we are keeping those going forward.
@okwolf Sounds good.
@mindplay-dk @zaceno Have you ever had to "unmount" your program?
Since I handle dynamic widgets through conditional rendering, I'm not sure an unmount is really necessary any more. Using a boolean flag to render or not render a widget makes more sense than directly unmounting it. If you need to do clean up, there's lifecycle events.
Hi @rbiggs would you be able to share some sample code on your solution? I'm having trouble doing such a thing because now we can't render/patch with null or "" for empty state. Thanks.
@jorgebucaran In hyperapp-nestable I do it (since a nestable component is an app in itself) and like others have suggested, I use ondestroy
What about supporting both patch(null or lastVNode, null, container)?
Oh you’re talking about an app unmounting itself! That’s a need I have not yet come across.
@van-nguyen, here a simple example.
import { h, patch } from 'superfine'
let isLoggedIn = true
function UserGreeting(props) {
return <h1>Welcome back!</h1>
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>
}
function Greeting(props) {
return props.isLoggedIn ? <UserGreeting /> : <GuestGreeting />
}
function LoginButton(props) {
return (
<button class='login' onclick={() => handleLogin()}>
Login
</button>
)
}
function LogoutButton(props) {
return (
<button class='logout' onclick={() => handleLogin()}>
Logout
</button>
)
}
function handleLogin() {
isLoggedIn = !isLoggedIn
login = patch(login, <LoginControl />, document.body)
}
function LoginControl() {
return (
<div class='greeting-jumbotron'>
<Greeting isLoggedIn={isLoggedIn} />
{
isLoggedIn && <LogoutButton />
}
{
!isLoggedIn && <LoginButton />
}
</div>
)
}
let login = patch(null, <LoginControl />, document.body)
Here it is live on Codepen
I like this patch(null, null, container) because I think Superfine is a low-level api for vdom. I don't like adding new function to Superfine. but I like adding umount(container) to Hyperapp.
@uchcode What do you think is the minimal spec (behavior-wise) for this functionality?
I mean, what does it do other than make your VDOM go away?
I'm wondering if maybe we could change the order of parameters for patch with the node argument last. That way, for the first render you could just do this:
// instead of let login = patch(null, <LoginControl />, document.body)
let login = patch(<LoginControl />, document.body)
And then later use:
login = patch(<LoginControl />, document.body, login)
@rbiggs Nothing to do with this issue? But yeah, I wondered about that too at some point, but chances are you are using patch to create a HOF like render that encapsulates this logic, where the lastNode is already available, as null/undefined on the first patch and then overwritten with the actual previous node for future patches.
I also find the current signature more straightforward.
Not all renders have to look like that by the way. In theory, we could put together a pure view framework that is essentially a reduce loop.
const loop = (last, next) => patch(last, next, document.body)
and use it like so:
allTheNodesInTheWorld.reduce(loop, null)
See here for a practical application in Superfine tests.
@jorgebucaran It is enough to go away VDOM becase Superfine already has onremove/ondestroy event.
I need to garbage collection of the user code for Superfine at the time of unmounting.
However, I understand that it is difficult because Superfine does not manage user code.
But I'm glad if it's possible.
@uchcode I want to add this feature, one way or another, I just would like to discuss what behavior we all want.
I'm looking forward to seeing this implemented. My preference would be patch(null, null, container) since it goes well with Superfine being a low-level api.
Thanks, for the input @jimfranke. What do you think should happen when you run patch(null, null, container)?
@jorgebucaran I think the container element that is being passed to the patch function should be returned to it's initial (empty) state. Or am I missing something here?
That means the root element (not the container) should be removed, therefore it should disappear from the page. Sounds reasonable.
@jorgebucaran Yes, this would be my preferred behaviour :)
Unmounting (calling life-cycle events) would just be patch(lastState, null, container) right?
Describing this as "unmounting" doesn't really make much sense though, as nothing gets "mounted" in the first place - the library is stateless, it isn't mounting a component in the DOM or something, it's just simply "patching", according to the new/old state you provide.
If you provide a null state, it removes the nodes - still just a "patch" by any other name.
Just my two cents.