question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unnecessary renders on parent update when $attrs is bound

See original GitHub issue

Version

2.6.10

Reproduction link

https://codepen.io/anon/pen/zQVRgG?editors=1010

Steps to reproduce

Type something into the first field

Uncomment line 8 or 14 then try again

What is expected?

In console:

Render a

What is actually happening?

In console:

Render a
Render b

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:8
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

7reactions
KaelWDcommented, Aug 6, 2019

The workaround I’m using for now is to mutate a single object instead:

data: () => ({
  $_attrs: {},
  $_listeners: {},
}),
watch: {
  // Work around unwanted re-renders: https://github.com/vuejs/vue/issues/10115
  // Make sure to use `v-bind="$data.$_attrs"` instead of `v-bind="$attrs"`
  $attrs: {
    handler (val) {
      for (const attr in val) {
        this.$set(this.$data.$_attrs, attr, val[attr])
      }
    },
    immediate: true
  },
  $listeners: {
    handler (val) {
      for (const listener in val) {
        this.$set(this.$data.$_listeners, listener, val[listener])
      }
    },
    immediate: true
  }
},

https://codepen.io/anon/pen/rXpGbj?editors=1010

I 100% guarantee there’s bugs in this btw.

0reactions
gaokuncommented, Nov 26, 2020

Consider this scenario:

<my-button v-if="visible" />
<my-button v-else detail />

If we toggle visible once, detail will be in $_attrs even visible is true. I think the root cause is vue v-dom diff policy.

There are three ways to help this out:

  1. use v-show instead of v-if
<my-button v-show="visible" />
<my-button v-show="!visible" detail />
  1. add different key to these two components
<my-button v-if="visible" key="a" />
<my-button v-else="visible" key="b" detail />
  1. delete attributes which wasn’t in $attrs any more. (like ‘detail’) [the same with $listeners]
  $attrs: {
    handler (val) {
      const oldKeys = Object.keys(this.$data.$_attrs)
      for (const attr in val) {
        this.$set(this.$data.$_attrs, attr, val[attr])
        const index = oldKeys.indexOf(attr)
        if (index > -1) {
          oldKeys.splice(index, 1)
        }
      }

      for (const attr of oldKeys) {
        this.$delete(this.$data.$_attrs, attr);
      }
    },
    immediate: true
  },
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to prevent re-rendering of components that have not ...
I have a component that consists of several other components such as text fields, and when an input is made to the text...
Read more >
Lightning - Rerender child components in aura:iterable after ...
I have a component (let's call it ParentComponent ) which has one main attribute -> object with nested objects within - attributes. I'm...
Read more >
Optimizing React performance by preventing unnecessary re ...
This article explains how to update components only when necessary, and how to avoid common causes of unintentional re-renders. Use React.memo ...
Read more >
Refs and the DOM - React
In the typical React dataflow, props are the only way that parent components interact with their children. To modify a child, you re-render...
Read more >
Using the React.cloneElement() function to clone elements
This argument can be a React element or a component that renders a ... the props of a parent component's children while avoiding...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found