From a34ffffffac32be4efac483c580496ae1ff76ae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20van=20Br=C3=BCgge?= Date: Mon, 3 Sep 2018 21:41:25 +0300 Subject: [PATCH] Explain insertBefore in README --- README.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/README.md b/README.md index 9f37f9b..82ae909 100644 --- a/README.md +++ b/README.md @@ -708,3 +708,43 @@ Here are some approaches to building applications with Snabbdom. Be sure to share it if you're building an application in another way using Snabbdom. + +## Common errors + +``` +Uncaught NotFoundError: Failed to execute 'insertBefore' on 'Node': + The node before which the new node is to be inserted is not a child of this node. +``` +The reason for this error is reusing of vnodes between patches (see code example), snabbdom stores actual dom nodes inside the virtual dom nodes passed to it as performance improvement, so reusing nodes between patches is not supported. +```js +var sharedNode = h('div', {}, 'Selected'); +var vnode1 = h('div', [ + h('div', {}, ['One']), + h('div', {}, ['Two']), + h('div', {}, [sharedNode]), +]); +var vnode2 = h('div', [ + h('div', {}, ['One']), + h('div', {}, [sharedNode]), + h('div', {}, ['Three']), +]); +patch(container, vnode1); +patch(vnode1, vnode2); +``` +You can fix this issue by creating a shallow copy of the object (here with object spread syntax): +```js +var vnode2 = h('div', [ + h('div', {}, ['One']), + h('div', {}, [{ ...sharedNode }]), + h('div', {}, ['Three']), +]); +``` +Another solution would be to wrap shared vnodes in a factory function: +```js +var sharedNode = () => h('div', {}, 'Selected'); +var vnode1 = h('div', [ + h('div', {}, ['One']), + h('div', {}, ['Two']), + h('div', {}, [sharedNode()]), +]); +```