Reputation: 243
I have a question regarding using reactive variables from component3 in my example in component 2. I have two checkboxes in component2 and I am having a reactive array that I want to use in component 2 but it does not quite work the way I want it to work. The repl can be found here: https://svelte.dev/repl/b8109591f22541949309be8404336afa?version=3.49.0
This is the main app
<script>
import Component2 from './Component2.svelte';
import Component3 from './Component3.svelte';
</script>
<Component3/>
<Component2/>
Component 2:
<script>
import a2 from './Component3.svelte';
</script>
{#if a2[0]}
<p>
Hi
</p>
{:else}
<p>
Not Hi
</p>
{/if}
Component 3
<script>
let initial_categories = [
{name: 'SPINS', checked: true},
{name: 'TRAIN', checked: true}
]
let vec_names = [
'SPINS', 'TRAIN'
]
export let a2 = [];
$: {
a2 = [];
for(let i = 0; i < initial_categories.length; i++) {
let stringify = JSON.stringify(initial_categories[i]);
stringify = JSON.parse(stringify)["checked"];
a2 = a2.concat(stringify);
}
}
</script>
{#each initial_categories as { name, checked }}
<label class="cats">
<input type=checkbox bind:group={vec_names} bind:checked={checked} name="Category" value={name}>
{name}
</label>
{/each}
{a2}
Upvotes: 4
Views: 4126
Reputation: 184376
This does not work:
<script>
import a2 from './Component3.svelte';
</script>
a2
is simply the constructor of Component3
with a bad name.
You can only export variables that are not bound to component instances from the context="module"
script, and those variables will not be reactive, so you need to use stores to preserve reactivity across components.
So something like this in #3:
<script context="module">
import { writable } from 'svelte/store';
export let a2 = writable([]);
</script>
<script>
// ...
$a2 = [];
for(let i = 0; i < initial_categories.length; i++) {
// ...
$a2 = $a2.concat(stringify);
}
</script>
And the import will be named instead of the default in #2:
<script>
import { a2 } from './Component3.svelte';
</script>
{#if $a2[0]}
<p>Hi</p>
{:else}
<p>Not Hi</p>
{/if}
I would recommend defining a shared state higher in the hierarchy and passing it down to the components instead of doing the above. This can be done via props or via a context. With props the store does not need to used as long as the props are using bind:
on the components that modify state.
E.g. in the main component:
<script>
import Component2 from './Component2.svelte';
import Component3 from './Component3.svelte';
let state = [];
</script>
<Component3 bind:state />
<Component2 {state} />
Then just add export let state
to the other two.
Upvotes: 4