Svelte: Spreading $$props to nested Child triggers reactive 'props' statement in every nested Child inside every Parent instance

Created on 9 Jun 2020  ·  5Comments  ·  Source: sveltejs/svelte

Having multiple Parent.svelte components with a nested Child.svelte component and passing all props to Child by spreading Parent's '$$props' to it: changing props on one Parent instance will trigger reactive 'props' statements of every nested Child inside every Parent instance.

Here is the REPL demonstrating the issue (incl. working / not working as expected code): https://svelte.dev/repl/c7948002ddec40aea93d1447d0fc9aa9?version=3.23.0

Expected behavior:
Changing props on one Parent triggers only reactive 'props' statement of it's Child, not also of all other Parent instances.

I've asked a question on the Svelte discord 'support' server and got this useful responses:
https://discord.com/channels/457912077277855764/506988048375087114/719672553291120790
https://discord.com/channels/457912077277855764/506988048375087114/719678060680577029

Chrome 83.0.4103.61, Windows 10, Svelte 3.23.0, Rollup

The bug is not severe to me as there is a workaround (actually more common workflow) by just exporting all props in Parent and passing them one by one to Child (see REPL above).

Thanks!

props reactivity bug has pr

All 5 comments

The issue here is that in the REPLs top-level component's update (p) function, it calls $set even if there are no changes:

const parent0_changes = {};
if (dirty & /*props1*/ 1) parent0_changes.props = /*props1*/ ctx[0];
parent0.$set(parent0_changes);

And then in the Parent component which uses a $$props spread in its template, the $set function always invalidates $$props even if the incoming props object is empty:

$$self.$set = $$new_props => {
  $$invalidate(0, $$props = assign(assign({}, $$props), exclude_internal_props($$new_props)));
};

So these two combine to make situation where any time something changes in the top-level component, all of its components go through state invalidation.

IMO the obvious fixes would be one or both of these:

  1. Check the changes object in the update function and don't call $set if it's empty.
  2. $set inside a component that uses $$props should check if $$new_props actually has any keys.

Someone more familiar with the Svelte internals may have a better idea though.

The issue here is that in the REPLs top-level component's update (p) function, it calls $set even if there are no changes:

☝️ but the issue is not limited to REPL, I stumbled over it locally (Svelte 3.23.0) and then tried to test it more isolated on REPL.

I was just referring to the example in the REPL and the code that was compiled from it, not the actual REPL component.
On Jun 9, 2020, 4:17 AM -1000, Vatroslav Vrbanic notifications@github.com, wrote:

The issue here is that in the REPLs top-level component's update (p) function, it calls $set even if there are no changes:
☝️ but the issue is not limited to REPL, I stumbled over it locally (Svelte 3.23.0) and then tried to test it more isolated on REPL.

You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or unsubscribe.

I was just referring to the example in the REPL and the code that was compiled from it, not the actual REPL component.

ah, ok, I misunderstood it, sorry. 😬

Was this page helpful?
0 / 5 - 0 ratings

Related issues

robnagler picture robnagler  ·  3Comments

plumpNation picture plumpNation  ·  3Comments

angelozehr picture angelozehr  ·  3Comments

AntoninBeaufort picture AntoninBeaufort  ·  3Comments

bestguy picture bestguy  ·  3Comments