-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Node level lifecycle hooks not always firing #165
Comments
yes. besides will/didRecycle, vnodes hooks are fired by the dom reconciler in conjunction with dom insertion/reorder/removal events. the old vnode's willRecycle should fire when its dom element is adopted by domvm to represent a new vnode and the element is patched to match it. in an unkeyed scenario this effectively means that you need to have the hooks defined on both the old and the new vnodes.
keying the nodes should work to prevent dom recycling [1], however, it doesnt prevent new vnode creation. everything you want on the vnode must be (re)defined on the new vnode during each render cycle. if you need to store anything on the vnode, you should use i'm gonna close this, but let me know if further clarification is needed. i'll add this to the WIP docs todo. [1] http://leeoniya.github.io/domvm/demos/playground/#lifecycle-hooks |
oops, you're right. i need to test your issues more carefully since i always seem to explain things you already understand. there's a EDIT: interestingly, const el = domvm.defineElement;
let show = true;
const _hooks = {
willRemove: (n) => console.log("willRemove"),
didRemove: (n) => console.log("didRemove"),
};
const View = {
render: (vm, data) =>
el("div", [
show ? el('div', {_hooks: _hooks}) : null
])
};
var vm = domvm.createView(View).mount(document.body);
setTimeout(() => {
show = false;
vm.redraw();
}, 1000); |
this should be fixed. thanks for the report! |
I think you may have fixed a separate issue. In my case, none of the will* hooks ever fire on the initial render. On a subsequent redraw Does that sound normal? |
no, that sounds abnormal. most of the vnode hooks fire here [1] just before actual dom insertion/re-insertion. i dont see how they would not fire unless your view is not actually mounted. are you able to repro in a fiddle? [1] https://github.com/leeoniya/domvm/blob/3.x-dev/src/view/dom.js#L102 |
there is a difference between whether key changes of vm root nodes cause dom node removal/recreation. EDIT: now fixed by 8990398 (below examples should all work the same after jsfiddle's cache expires) plain template dom elements will get removed and recreated: vm root dom elements will always be recycled: but if the key is defined at the view level, then it works the same as the first case: this is an inconsitency |
https://jsfiddle.net/kmcrqfw7/ In both Safari and Chrome If you remove the array around main content, then the only hooks logged are This seems like a pretty basic tree and makes me think #164 is real. |
the way your example behaves is by design. you're only defining hooks on the your original, a bit easier to read: https://jsfiddle.net/kmcrqfw7/1/ they all work fine.
that's not related as it appears to have too much dom created/retained rather than overly-aggressive recycling which happens here. so, basically the opposite of that issue :) |
This is what I initially suspected with:
When you add These fiddles were obviously trimmed down to bare bones, but in complex real world apps with large trees, I need to touch the dom manually, and placing that code in the node level hooks seemed ideal. But now I'm not even sure why you would even need these node-level hooks in your application space. Isn't it irrelevant to the app if a node is recycled, inserted, or re-inserted? That seems like a low level decision made by the library. Doesn't the app more likely care about animating the element in/out or initializing some code when the dom is ready? So this brings me back to:
|
this is because keyed nodes (alt content) are allowed recycle the dom of unkeyed nodes (main content) which are no longer present in the vtree. if you key both nodes, then the recycling is prevented: https://jsfiddle.net/kmcrqfw7/5/ and your hooks will fire when the dom gets recreated. so a sub-view is not required.
all dom elements are accessible via BTW:
the primary use case is setting up css transitions. the secondary use case is embedding third-party widgets, as in http://leeoniya.github.io/domvm/demos/playground/#embed-tweets it's hard to provide the idiomatic way to get something done when all i'm shown is a very small part of the picture. "need access to dom" needs to be qualified with "when?" and "for what?". without having this information we can talk past each other in generalizations for a long time :) the vast majority of domvm codebases will not need hooks at all. but i can't tell you how to avoid hooks to get your thing done when i don't understand the endgame. [1] https://github.com/leeoniya/domvm/blob/3.x-dev/src/view/initElementNode.js#L74-L81 |
But isn't this precisely what these hooks are failing at. There is no way, with pure node-level hooks, to do either of those reliably, because of the likelihood that the vnode will used a recycled dom element and therefore never have an opportunity to trigger an animation or 3rd party widget.
What about also falling back the CSS hyperscript string? |
I think my confusion most stemmed from thinking domvm provided deterministic setup and teardown hooks at the vnode level. Because most of my tree is really only distinguishable by the first hyperscript argument, a lot of recycling happens. but I think I get it now. Essentially it boils down to needing to listen to all of |
domvm does the following during redraw:
hopefully that illustrates why hook determinism can only be acheived by ensuring recycling determinism. you dont have to add hooks to everything, you just have to add keys to ensure the dom is not recycled non-deterministicly. it's possible to modify domvm's step 2 to prevent the dom of any keyed vnodes from being recycled at all, which would eliminate the need to key all siblings and would add determinism to keyed vnodes (probably a good idea). i think perhaps this was your expectation, and it's a reasonable one. i'll have a patch for this later today. |
i think this is now officially fixed: https://jsfiddle.net/kmcrqfw7/7/ also tagged v3.0.3 thanks! |
This helped out quite a bit. I'm running solid on 3.0.3 now. Thanks! |
Is there any guarantee that a node's
willInsert
hook will be called? I have a scenario where an element ends up in the dom without firing any lifecycle hooks. On a later redraw,willRecycle
is finally the first hook to fire.I also have another scenario that sometimes barfs because
node.dropdown === null
indidRemove
:I'm guessing these mismatches are due to the dom element pooling. I tried adding
_key
without luck. Maybe I am missing something. Is a sub-view required to encapsulate this type of life-cycle?The text was updated successfully, but these errors were encountered: