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

Template is not updating when passing vnode to Dynamic Component #4903

Closed
sqal opened this issue Nov 4, 2021 · 8 comments
Closed

Template is not updating when passing vnode to Dynamic Component #4903

sqal opened this issue Nov 4, 2021 · 8 comments
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. has workaround A workaround has been found to avoid the problem 🐞 bug Something isn't working

Comments

@sqal
Copy link
Contributor

sqal commented Nov 4, 2021

Version

3.2.21

Reproduction link

https://sfc.vuejs.org/

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.

@sqal
Copy link
Contributor Author

sqal commented Nov 4, 2021

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

@LinusBorg LinusBorg added the 🐞 bug Something isn't working label Nov 5, 2021
@LinusBorg
Copy link
Member

LinusBorg commented Nov 5, 2021

Seems like a bug, definitely. The new subtree is present in the instance's vnode, but DOM wasn't patched:

image

@zhaozhongyu
Copy link

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'}`)

@edison1105
Copy link
Member

edison1105 commented Nov 5, 2021

Actually, it's a bug. should not take fast path when dynamicChildren is empty.
image

the root cause is we doesn't track block here.
image

@sqal
Copy link
Contributor Author

sqal commented Nov 5, 2021

@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

@edison1105
Copy link
Member

@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 edison1105 added 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. has workaround A workaround has been found to avoid the problem labels Nov 6, 2021
@sqal
Copy link
Contributor Author

sqal commented Nov 6, 2021

@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.

@edison1105
Copy link
Member

@sqal
A vnode is the result of template compilation. If you want to create a vnode with the h function, you have to make sure it is correct and can be rendered into the DOM.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. has workaround A workaround has been found to avoid the problem 🐞 bug Something isn't working
Projects
None yet
4 participants