Template is not updating when passing vnode to Dynamic Component
Version
3.2.21
Reproduction link
Steps to reproduce
- click on some checkbox
What is expected?
Template should update to show information about the selected fields
What is actually happening?
Nothing happens even though "render" function is called.
Additional information
There's a workaround for this issue. Instead of using <component :is="vnode">
I replaced it with a Functional component that receives a vnode as a prop and returns it:
const Children = ({ children }) => children
but I am not sure if this is the correct way to handle my use case or if it is a bug that needs to be fixed.
Just wanted to add that I have a use case for rendering an existing vnode in the template. I'm building a DataTable component where my api, for example returns a list of table headers. Each object contains a "render" function that returns already created vnode. Unfortunately, Dynamic component is the only "official" way to render existing vnode inside of SFC and without workaround posted above, it doesn't work as it should - example
Seems like a bug, definitely. The new subtree is present in the instance's vnode, but DOM wasn't patched:
return a render function will work. and i did not think it is a bug.
return () => h('div', {
style: { color: isChecked ? 'green' : 'red' },
}, `[ ${id} ] ${isChecked ? 'checked' : 'unchecked'}`)
Actually, it's a bug. should not take fast path when dynamicChildren is empty.
the root cause is we doesn't track block here.
@edison1105 while this issue is still open. Do you know why I also can't render a Fragment which may have falsy values as its children? Will your PR fix this case? check example. It works in plain JS though
@sqal this code not working because component should be a vnode not an vnode array.
const array = () => [
h('div', 'foo'),
h('div', 'bar')
]
should change to
const array = () => h(Fragment,null,[
h('div', 'foo'),
h('div', 'bar')
])
this code not working because every item in children array must be a vnode.
return h(Fragment, null, [
h('div', 'foo'),
// ERROR: Cannot read properties of null (reading 'el')
null,
//false,
h('div', 'bar'),
])
@edison1105
every item in children array must be a vnode
hmm but doesn't have to when using render function in plain JS? (check Comp.vue in my demo),. A little bit of inconsistency here, but if I have to filter out falsy values myself that's fine.