Vue: Rendering async loaded component is causing attrs change.

Created on 16 Sep 2019  ·  4Comments  ·  Source: vuejs/vue

Version

2.6.10

Reproduction link

https://codesandbox.io/s/vue-template-7hwty

Steps to reproduce

  1. Create component with render function which can render another component after time.
  2. Rendering component after promise resolution/timeout is causing render twice and change of $attrs if child component has any prop with key equal to attr.
  3. Comment prop in targetComponent and reload page.
  4. All attrs are fine again.

What is expected?

Render function is called once and $attrs of component are not changed.

What is actually happening?

Render is called twice and attrs which has key same as props of child component are removed.


I created on my project custom loader component which has to handle loading of lazy loaded components and networking errors, because I can't use https://vuejs.org/v2/guide/components-dynamic-async.html#Handling-Loading-State in my case. This bug can be ommited by not adding downloaded component to reactivity (outside data as variable).

bug has workaround

All 4 comments

Using a copy of $attrs: {...this.$attrs} also removes the problem

Maybe you should use props to resolve this problem:

  render(h) {
    console.log("Attributes of loader:", this.$attrs);
    if (this.targetComponent) {
      return h(this.targetComponent, {
        props: this.$attrs  // Change attrs to props,not `attrs: this.$attrs`
      });
    } else {
      return h("div", "Component is loading");
    }
  }

because you are trying to get props in

const targetComponent = {
  props: {
    // COMMENT PROP
    someProp: {
      type: String
    }
  },
  render(h) {
    console.log("Props of target", this.$props); // You can not get $props when render params only has attrs
    return h("div", "WITH PROP:" + this.someProp);
  }
};

Both creating copying of attrs and passing with props resolve my problem, but I am curious still why parent component $attrs are changing because of rendering child which contain props with same key?

It's because the $attrs object is reassigned. I knew I saw this issue already somewhere else:
Duplicate of https://github.com/vuejs/vue/issues/10115

Was this page helpful?
0 / 5 - 0 ratings