Reputation: 4156
Reproduction: https://svelte.dev/playground/4424d522f50847f0b872a094b7b2198b?version=5.18.0
I cannot understand why this error:
[svelte] binding_property_non_reactive
`bind:value={content.one}` (Form.svelte:5:19) is binding to a non-reactive property
https://svelte.dev/e/binding_property_non_reactive
Code:
App.svelte:
<script>
import Form from "./Form.svelte";
let changed = $state(false);
let content = $derived({one: `hello ${changed}`, two: changed });
</script>
<Form bind:content={() => content, (v) => content = v} />
Form.svelte:
<script>
let { content = $bindable() } = $props();
</script>
<input type="text" bind:value={content.one} />
Upvotes: 0
Views: 87
Reputation: 548
You cannot bind to a derived state, if you want your content
to both bindable and reactive to change
then you can declare it with a $state
rune and use an $effect
to update it whenever change
updates like this:
<script>
import Form from "./Form.svelte";
let changed = $state(false);
let content = $state({one: `hello ${changed}`, two: changed });
$effect(() => {
content = {one: `hello ${changed}`, two: changed }
});
</script>
changed: {changed} <br>
content: {JSON.stringify(content)} <br> <br>
<!-- This does not work! -->
<!-- <Form bind:content /> -->
<Form bind:content={() => content, (v) => content = v} />
<br><br>
<button type="button" onclick={() => changed = !changed}>
change from App
</button>
This will give you a warning that State referenced in its own scope will never update
but it should still work, if you want to get rid of the warning then declare the content
using a closure like this:
let content = $state({one: `hello ${(() => {return changed})()}`, two: () => {return changed} });
Here's your REPL working with this fix
Upvotes: 1