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

Self-assignments of each contexts don't trigger proper reactivity #3217

Closed
Conduitry opened this issue Jul 10, 2019 · 3 comments
Closed

Self-assignments of each contexts don't trigger proper reactivity #3217

Conduitry opened this issue Jul 10, 2019 · 3 comments
Labels

Comments

@Conduitry
Copy link
Member

Clicking the items here does not cause them to toggle:

<script>
	let array = [{ flag: false }, { flag: false }];
	function mutate(item) {
		item.flag = !item.flag;
	}
</script>

{#each array as item}
	<div on:click={() => { mutate(item); item = item; }}>
		{item.flag ? 'Yes' : 'No'}
	</div>
{/each}

I believe this should work. There also seem to be a few other permutation that aren't working (having mutate return the item, and then having the click handler do item = mutate(item);. I thought that reassigning to an {#each} context that can be traced back to a top-level variable would also invalidate that top-level variable - and it seems like it does, in certain cases - but I'm not entirely sure that the intended behavior is here. It might be simplest if we just said 'no, only assignments to top-level variables triggers re-rendering', but that's probably not ideal.

@Conduitry Conduitry added the bug label Jul 10, 2019
@brucou
Copy link

brucou commented Jul 11, 2019

That is a tricky one in my opinion. Equality of values vs. equality of references can lead to subtle issues down the road. By tracking the content of the array for changes, you would end up having to track recursively those contents (imagine the array contains arrays, or other objects). If you do that for arrays, you logically have to do it for objects too (because arrays are objects or else you have to explain why one and not the other) etc. Then you have the case when the current behaviour is actually the desired behaviour (e.g. don't track inner changes) so you would have to deal with that use case with maybe extra syntax, and that's more complexity yet again. In short. there is plenty of complexity hidden there and a ton of bugs.

I actually think it is simpler to say to educate around/document reference equality. Here how how mobx explains its reactivity sysem (which is pretty much similar to the Svelte's one by the one): https://github.com/mobxjs/mobx/blob/gh-pages/docs/best/react.md#common-pitfall-consolelog

@pngwn
Copy link
Member

pngwn commented Aug 15, 2019

Comment from my dupe:

Describe the bug
When performed inside an inline function with curly braces, assignments to array items inside each blocks do not correctly invalidate the array but instead invalidate the array item.

To clarify, it seems that assignments to an item when inside an each loop correctly invalidate the array itself when the assignment is performed in an inline arrow function without curly braces. When the curly braces are present Svelte instead invalidates whatever variable was assigned to, at this point Svelte no longer seems to know that we are in an array.

To Reproduce
REPL

On removing the curly braces, Svelte will correctly invalidate the array.

Expected behaviour
The array should be updated, invalidated.

Severity

There are workarounds, it isn't the worst thing that has ever happened in the world.

@Conduitry
Copy link
Member Author

This looks like it was also fixed by #3533.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants