-
Hello people! I'm new and trying to learn Svelte! I have read most of the tutorial, and I'm now trying to make a color picker app that supports different color spaces. One of the problems I face is getting an error (or warning?) that says:
But how can the value be "non-reactive", when I used $state for it? The source code for my example, is here (notice that it's the dev branch). You can see the three files inside the |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 5 replies
-
Hello! I've taken a look at your color picker app code and can explain why you're getting the "binding_property_non_reactive" error. Why This HappensYour current approach has two main issues:
Here is how I would approach this if have understood correctly what you want to achieve: 1. Update Your Slider.svelte<script lang="ts">
// Accept a direct sliderValue instead of accessing the sliders object.
// It should be a bindable prop for the parent to bind to.
let { name, max, sliderValue = $bindable() } = $props();
</script>
<input id="{name}_slider" type="range" min="0" max={max} bind:value={sliderValue} />
<input type="number" min="0" max={max} value={sliderValue} />
2. Update Your Space.svelte<script lang="ts">
import Slider from '$comp/Slider.svelte';
// Accept props from parent component
// If you want the parent to bind to the values as well, use $bindable() again
let { name, max1, max2, max3, value1 = $bindable(), value2 = $bindable(), value3 = $bindable() } = $props();
</script>
<div>
<Slider {name} max={max1} bind:sliderValue={value1} />
<Slider {name} max={max2} bind:sliderValue={value2} />
<Slider {name} max={max3} bind:sliderValue={value3} />
</div>
3. Update Your ColorSpaces.svelte<script lang="ts">
import Space from '$comp/Space.svelte';
// Keep your state object
const sliders = $state({
rgb1: 0,
rgb2: 0,
rgb3: 0,
hsv1: 0,
hsv2: 0,
hsv3: 0,
});
const rgb_props = {
name: "rgb",
max1: 255,
max2: 255,
max3: 255,
};
const hsv_props = {
name: "hsv",
max1: 355,
max2: 100,
max3: 100,
};
$effect(() => {
if (sliders.rgb1) {
console.log("rgb1 changed to", sliders.rgb1);
}
// ...other effects
});
</script>
<div id="ColorSliders">
<Space {...rgb_props}
bind:value1={sliders.rgb1}
bind:value2={sliders.rgb2}
bind:value3={sliders.rgb3} />
<Space {...hsv_props}
bind:value1={sliders.hsv1}
bind:value2={sliders.hsv2}
bind:value3={sliders.hsv3} />
</div>
The Key InsightSvelte's reactivity system works best when:
This solution maintains the same functionality but properly preserves reactivity throughout your component hierarchy by keeping a clean data flow. Further ImprovementsIf you want to share state across multiple components, you have several options:
The first approach aligns best with Svelte's runes system and is generally recommended for new projects. Hope this helps solve your "non-reactive" binding error! Let me know if you need any clarification. |
Beta Was this translation helpful? Give feedback.
Hello! I've taken a look at your color picker app code and can explain why you're getting the "binding_property_non_reactive" error.
Why This Happens
Your current approach has two main issues:
<script>
tag from.svelte
files. If you need to export a value, you should do it from the<script module>
tag. More info here: https://svelte.dev/docs/svelte/svelte-files#script-moduleHere is how I would approach this if have understood correctly what you want to achieve:
1. Update Your Slider.svelte