-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
$state() of Array : incorrect behavior of indexOf()/findIndex() with object #11556
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
Comments
Maybe use As I understand it, there's no way to both make an object/array deeply reactive and maintain equality with the original object/array at the same time, since you have to add extra stuff to make it reactive, and you wouldn't want those extra stuff to propagate back to the original object. |
I think this is more a documentation problem. Svelte uses proxies to make deep reactivity work, and thus equality of things you put in state will never match the same thing as what you put in, because they're all wrapped with proxies. |
The workaround seems to reactify the searched value: the $state never creates wrappers (not sure how reliable this behaviour is). const value = {};
$state(value) === $state(value); // true
$state(value) === $state($state(value)); // true
const arr = $state([ value ]);
arr.includes($state(value)); // true The proxy could alter the behaviour of search methods, but it won't resolve cases like |
@dummdidumm I feel like the new warnings largely address this issue now. |
There needs to be more docs on this, the warning itself is somewhat vague without any additional explanation IMO. It could come as part of the general "more details on a warning" system we can put in place with how warnings are setup now. |
It might be worth documenting now whilst it’s fresh in your head. I don’t personally think it’s all that needed so maybe your documentation can help me understand your thought process. |
This should be addressed by #11613 |
Here is only for 1st line a solition in Svelte 5. I'm unhappy about so many extra runes... |
@dm-de It's not a problem if you reference things in state from the beginning. If you don't then you'll need to use |
#11613 add a partial fix for this, and now these lines will produce a warning state_proxy_equality_mismatch : items.findIndex(n => n === item); // WARN state_proxy_equality_mismatch This is fine, and the warning message is explicit enough :
=> So - items.findIndex(n => n === item);
+ items.findIndex(n => $state.is(n, item)); 👍 But for items.indexOf(item); // WARN state_proxy_equality_mismatch
=> How do we replace In fact here we should replace the - items.indexOf(item);
+ items.findIndex(n => $state.is(n, item)); So :
In "pseudo-code", the indexOf(item) {
if (item!=null && typeof item === 'object) {
// item is an object, use findIndex()
return this.findIndex(n => $state.is(n, item));
} else {
return /* original indexOf() */
}
} |
We're getting into monkey-patching territory with this, and I'm pretty sure everyone agrees that we shouldn't do that. |
Also add a detailed explanation which can later appear on the docs site closes #11556
This ticket should not be closed |
There is no more |
@zdila |
Describe the bug
When we used an
$state([])
, some basic function of Array have an incorrect behavior with object.It seems that all equality operations fail, as the object in the array is a proxy.
It’s really disturbing and not easy to understand...
Reproduction
Exemple in REPL : the buttons addRandomNumber, addRandomString and addRandomObject add a number/string/object in an array, and logs the index.
This works as espected for number and string, but fails for objects.
REPL
Logs
No response
System Info
Severity
annoyance
The text was updated successfully, but these errors were encountered: