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

Rendering async loaded component is causing attrs change. #10524

Closed
Mighty683 opened this issue Sep 16, 2019 · 4 comments
Closed

Rendering async loaded component is causing attrs change. #10524

Mighty683 opened this issue Sep 16, 2019 · 4 comments

Comments

@Mighty683
Copy link

Mighty683 commented Sep 16, 2019

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

@posva
Copy link
Member

posva commented Sep 17, 2019

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

@joe223
Copy link

joe223 commented Sep 20, 2019

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);
  }
};

@Mighty683
Copy link
Author

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?

@posva
Copy link
Member

posva commented Sep 22, 2019

It's because the $attrs object is reassigned. I knew I saw this issue already somewhere else:
Duplicate of #10115

@posva posva closed this as completed Sep 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants