Subscribe on changes!

can not update createVNode instance

avatar
Jan 3rd 2024

老师来发声了,赞赞赞

avatar
Jan 3rd 2024

Can you set effect.dirty to true before calling update?

For example like this: playground

avatar
Jan 3rd 2024

Can you set effect.dirty to true before calling update?

For example like this: playground

component.update is not public api. effect.dirty also not public api. we should avoid use this. However, due to historical reasons, if the official can support solving the component.update problem. Historical versions will be compatible. If not, we will use public api to reconstruct this code as much as possible instead of not safe api again.

avatar
Jan 3rd 2024

Using internal API/behaviours can cause these sort of issues, since they are not public they might not be tested directly and the tests are done by other places that rely on that behaviour.

My personal opinion and not talking as Vue team or any official manner:

I think there's an incorrect usage of the internal function but on the other hand I would expect .update to be a very similar behaviour to $forceUpdate which would trigger a re-render regardless of dependencies. Is also odd that the stateful component works and stateless does not, making me think this might be a bug, altho in template usages it works as expected. As for effect.dirty = true, there's some usages in the code base to trigger this exact behaviour, I cannot recommend that, because there's no guarantee it will keep working in the future.

One way to solve this in most of v3 releases is to use cloneVNode to update the node:

// vm.component.update()
// I don't really recommend updating/mutating the props directly
VueRender(cloneVNode(vm, vm.component.props), domRef.value)
avatar
Jan 4th 2024

The correct usage with public APIs: for each update, you should be creating a new vnode with the new props and then call render again on the same DOM container:

const handleClick = ()=> {
-  Object.assign(vm.component.props, {num: ++num})
-  vm.component.update();
+  VueRender(createVNode(CompFunctional, { num: ++num }), domRef.value)
}

Demo

Closing as wontfix, as the workaround is relatively straightforward.