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

Properties are not reactive when using mountand $state props. #12904

Closed
LordTumnus opened this issue Aug 19, 2024 · 6 comments
Closed

Properties are not reactive when using mountand $state props. #12904

LordTumnus opened this issue Aug 19, 2024 · 6 comments

Comments

@LordTumnus
Copy link

Describe the bug

When creating a component in a .svelte.js using mount, and defining it's properties as a $state, a change in the property inside the component won't trigger effects defined in the module file.

Reproduction

// main.svelte.js
import Component from "./Component.svelte";
import {mount} from 'svelte'

let props = $state({count: 1});
mount(Component, {target: document.body, props});

props.count = 13; // works -> sets the property in the component

$effect.root(() => {
  $effect(() => {
    // never triggers when the button is clicked
    console.log(`Count changed to: ${props.count}`);
  });
});
// Component.svelte

<script>
    let {count} = $props()

    function increment() {
        count += 1;
    }          
</script>

<button onclick={increment}>
    clicks: {count}
</button>

Logs

No response

System Info

System:
    OS: macOS 14.3
    CPU: (8) arm64 Apple M1 Pro
    Memory: 61.89 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 21.2.0 - /usr/local/bin/node
    npm: 10.2.3 - /usr/local/bin/npm
  Browsers:
    Chrome: 127.0.6533.120
    Safari: 17.3
  npmPackages:
    svelte: ^5.0.0-next.225 => 5.0.0-next.225

Severity

annoyance

@trueadm
Copy link
Contributor

trueadm commented Aug 19, 2024

Should count be bindable()?

@Hugos68
Copy link

Hugos68 commented Aug 19, 2024

Should count be bindable()?

This does not fix it sadly: https://github.com/Hugos68/svelte-5-main--effect.root-not-working

@trueadm
Copy link
Contributor

trueadm commented Aug 19, 2024

Bindable works by checking if the object property is an accessor with a setter. In this case, it is not. If you make it so this is the case:

mount(Component, {target: document.body, props: {
  get count() {
    return props.count;
  },
  set count(v) {
    props.count = v;
  }
}});

Then you have two-way bindings working outside.

@Hugos68
Copy link

Hugos68 commented Aug 19, 2024

I thought this is what proxied $state already did for you? (Assuming props is an object)

@trueadm
Copy link
Contributor

trueadm commented Aug 19, 2024

I thought this is what proxied $state already did for you? (Assuming props is an object)

This is about props, not state. So no, it doesn't do this for you.

@LordTumnus
Copy link
Author

Thanks for the easy solution. I will mark this as closed

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

No branches or pull requests

3 participants