prop is not reactive when passed down in render function

688 views Asked by At

Reproducer: https://stackblitz.com/edit/vue-tjt1qp?file=src/components/ParentComponent.js

In the reproducer above, I expect the child to behave in the same way as the parent.

I am trying to pass props via render functions to child components.

const submitting = ref('...');
const childComponent = h(ChildComponent, { loading: submitting.value });

return () => h('div', props, [slots.default(), childComponent]);

However, they are not reactive. I read the vuejs docs on render functions, but couldn't find out what I am doing wrong. Obviously I am missing something... what is it?

2

There are 2 answers

3
tom On

Someone in the vuejs dischord channel helped me out.

Instead of writing

const childComponent = h(ChildComponent, { loading: submitting.value });

// render function
return () => h('div', props, [slots.default(), childComponent]);

In the example above, the childComponent's vNode is created only once. This is because setup functions are called once, while render functions get called multiple times, see. e.g., vueJs docs on declaring render functions. I need to make sure that the childComponent's vNode is re-rendered by shifting it inside the render function:

// render function
return () => {
  const childComponent = h(ChildComponent, { loading: submitting.value });
  return h('div', props, [slots.default(), childComponent]);
}

Alternatively, I could call the the hyperscript function h() inside the parents hyperscript function:

// render function
return () => h(
    'div',
    props,
    [
        slots.default(),
        h(ChildComponent, { loading: submitting.value })
    ]
);

Or, when assigning the child component's hyperscript function to a variable, wrap it inside a function

const childComponent = function () {
    return h(ChildComponent, { loading: submitting.value });
};
// render function
return () => h('div', props, [slots.default(), childComponent()]);
0
林逸舟 On
const childComponent = h(ChildComponent, { loading: submitting.value });

replace with

 const childComponent = h=>(h(ChildComponent, { loading: submitting.value }));

It works may be like computed.