Skip to content
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

Snabbdom removes null, causing unsafe reuse of elements #973

Open
cjohansen opened this issue Jun 17, 2021 · 0 comments
Open

Snabbdom removes null, causing unsafe reuse of elements #973

cjohansen opened this issue Jun 17, 2021 · 0 comments

Comments

@cjohansen
Copy link

It seems that Snabbdom removes null from the list of children prior to patching the DOM. This causes Snabbdom to consider elements that are not logically "the same element" to actually be the same, and unsafely reuses the DOM element.

An example follows:

var patch = snabbdom.init([
  snabbdom.styleModule
]);

var el = document.createElement('div');
document.body.appendChild(el);

var h = snabbdom.h;

vdom = patch(el,
             h('div', {}, [
               null,
               h('div', {}, ['Snabbdom'])
             ]));

setTimeout(function () {
  vdom = patch(vdom, h('div', {}, [
    h('div', {style: {
      opacity: 0.3,
      transition: "opacity 0.5s"}}, ['Hello']),
    h('div', {}, ['Snabbdom'])
  ]));
}, 2000);

When this first renders, it says "Snabbdom". After 2 seconds, it will say "Hello Snabbdom". The peculiar thing is that the "Hello" has its opacity animated from 1 to 0.3. This breaks with my expectation: I was expecting the DOM node to be inserted with a "starting opacity" of 0.3, and then apply transitions to any upcoming changes. This is indeed what happens if you recreate this example with React (the code where this was discovered was ported from React to Snabbdom).

Because Snabbdom has removed the null from the first render, it considers the initial "Snabbdom" element to be same as the "Hello" element in the update. Thus, when the element is being reused, the transition is carried out.

This problem can be manually side-stepped by using a key on the element, but it shouldn't be necessary, as Snabbdom can just use the element's position to know that reusing the DOM element in this case is not safe. But in order to do that, it must keep on to the null for longer than it currently does.

For now I've worked around this in dumdom by generating comment nodes in place of nulls, but that should in my opinion not be necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant