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

feat: add $state.is rune #11613

Merged
merged 4 commits into from
May 14, 2024
Merged

feat: add $state.is rune #11613

merged 4 commits into from
May 14, 2024

Conversation

trueadm
Copy link
Contributor

@trueadm trueadm commented May 14, 2024

This PR adds the $state.is rune. Fixes #11403.

Sometimes you might need to deal with the equality of two values, where one of the objects might have been wrapped in a with a $state proxy,
you can use $state.is to check if the two values are the same.

<script>
  let state = $state({});
  let object = {};

  state.object = object;

  console.log(state.object === object); // false because of the $state proxy

  console.log($state.is(state.object, object)); // true
</script>

This is handy when you might want to check if the object exists within a deeply reactive object/array.

Copy link

changeset-bot bot commented May 14, 2024

🦋 Changeset detected

Latest commit: c915f59

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
svelte Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@Rich-Harris Rich-Harris merged commit f488a6e into main May 14, 2024
7 of 8 checks passed
@Rich-Harris Rich-Harris deleted the state-is branch May 14, 2024 19:40
@7nik
Copy link

7nik commented May 14, 2024

For arrays, isn't

let item = $state(maybeRawItem);
let index = array.indexOf(item);

better than

let index = array.findIndex((item) => $state.is(item, maybeRawItem));

?
But the docs don't mention the first approach.

@trueadm
Copy link
Contributor Author

trueadm commented May 14, 2024

For arrays, isn't

let item = $state(maybeRawItem);
let index = array.indexOf(item);

better than

let index = array.findIndex((item) => $state.is(item, maybeRawItem));

? But the docs don't mention the first approach.

How do you mean? The first example won’t work?

@7nik
Copy link

7nik commented May 14, 2024

The first example is better for performance, but not mentioning it may force people to use the second approach.

@trueadm
Copy link
Contributor Author

trueadm commented May 14, 2024

The first example is better for performance, but not mentioning it may force people to use the second approach.

They should use the second approach here though?

@7nik
Copy link

7nik commented May 14, 2024

I doubt that many people are aware of

let foo = {};
$state(foo) == $state(foo); // true

and even may think the opposite and thus assume array.indexOf($state(foo)) won't work.

@trueadm
Copy link
Contributor Author

trueadm commented May 14, 2024

I doubt that many people are aware of

let foo = {};
$state(foo) == $state(foo); // true

and even may think the opposite and thus assume array.indexOf($state(foo)) won't work.

That’s what #11610 addresses

@7nik
Copy link

7nik commented May 14, 2024

So, if somebody carefully reads the docs and writes array.findIndex((item) => $state.is(item, foo)), will #11610 warn them to use array.indexOf($state(foo)) instead?

@trueadm
Copy link
Contributor Author

trueadm commented May 14, 2024

So, if somebody carefully reads the docs and writes array.findIndex((item) => $state.is(item, foo)), will #11610 warn them to use array.indexOf($state(foo)) instead?

No, because that's invalid usage of the $state rune. They should be using findIndex here instead. That's my entire point. If they are working with things that are both state, they don't get a warning, if they do then the warning suggests they should refactor to use something like findIndex as they need to incorporate $state.is.

@Nelhoa
Copy link

Nelhoa commented May 15, 2024

I don’t understand. Then this should not work as expected ?

class MyClass {}

let a = new MyClass()
let b = new MyClass()
let c = $state([a, b])

console.log(c[0] === a) // log 'true' as expected

But it works (REPL).

Not sure to get the point where $state.is() is usefull then.

@7nik
Copy link

7nik commented May 15, 2024

Only POJOs are proxied. Class instances aren't.

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

Successfully merging this pull request may close these issues.

Svelte 5: <select> options with object references.
4 participants