can not update createVNode instance
Vue version
3.4
Link to minimal reproduction
Steps to reproduce
when use functioal component, we can not update vnode(by createVNode).
Note: 3.3 is ok
What is expected?
can update like 3.3
What is actually happening?
can not update
System Info
No response
Any additional comments?
No response
Can you set effect.dirty
to true before calling update
?
For example like this: playground
Can you set
effect.dirty
to true before callingupdate
?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.
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)
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)
}
Closing as wontfix, as the workaround is relatively straightforward.