Prop & store sync issue in grandchild component

Viewed 84

I have two variables, a and b, and three components nested in one another: <Outer> -> <Middle> -> <Inner>. a is fed as a prop into <Outer>, which creates a context. This context includes a store for a and thereby allows <Inner> to subscribe to a. b is fed directly into <Inner> as a prop.

My goal is to update (increment) a and b in the same code block and have <Inner> receive both updated values before updating the DOM. The desired result, which happens when I remove <Middle>, looks something like this:

a = 0; b = 0; sum = 0

a = 1; b = 1; sum = 2

a = 2; b = 2; sum = 4

a = 3; b = 3; sum = 6

a = 4; b = 4; sum = 8

but $a and b inside <Inner> are no longer in sync as soon as I put <Middle> back in:

a = 0; b = 0; sum = 0

a = 1; b = 0; sum = 1

a = 1; b = 1; sum = 2

a = 2; b = 1; sum = 3

a = 2; b = 2; sum = 4

a = 3; b = 2; sum = 5

a = 3; b = 3; sum = 6

a = 4; b = 3; sum = 7

a = 4; b = 4; sum = 8

a = 5; b = 4; sum = 9

a = 5; b = 5; sum = 10

Is there any way for me to keep <Middle> but still achieve the effect I want? I'm using Svelte 3.44.2 and Chromium 93.0.4577.58. REPL can be found here: https://svelte.dev/repl/879a436fe96d4445a5ba870cd37436f4?version=3.44.2

Thanks!

1 Answers

Svelte by default 're-run reactive declarations whenever any of the referenced values change' so when the store updates the value of a it gets immediately updated in outer component and updates the refrence in inner component at this stage. then middle before fires first before firing the inner component then b gets updated which immediately updates the reference in inner-component again and the reactive statement of $: calculations re-evaluated again which reloads the loop.

this is your test without middle compenent

// on load

"outer before"
"inner calculations" ▶ Array(1)[ Object { … } ]
"inner before"
"inner after"
"outer after"

// on click

"outer before"
"inner calculations" ▶ Array(2)[ Object { … } , Object { … } ]
"inner before"
"outer after"
"inner after" 

...

// on load

"outer before"
"middle before"
"inner calculations" ▶ Array(1)[ Object { … } ]
"inner before"
"inner after"
"middle after"
"outer after"

// on click

"outer before"
"inner calculations" ▶ Array(2)[ Object { … } , Object { … } ]
"inner before"
"middle before"
"inner calculations" ▶ Array(3)[ Object { … } , Object { … } , Object { … } ]
"inner before"
"outer after"
"inner after"
"middle after"

i see no solution to this problem other than binding both values to be updated at the same time of the component life-cycle or pass both using the store to do the same.

Related