Reputation: 51
The example below has two files: index.svelte is hosted in the slot provided in __layout.svelte. When you click the button it should change the color of the box in the hosted page. The code below works fine if index.svelte is a child component, but does not work if index.svelte is a page hosted in the slot. I am sure this is because props work differently with hosted pages.
I have tried using setContext/getContext and a writable store to pass the information across, but I have not found a way to make this reactive so that the box color change takes effect immediately - everything I have tried requires reloading index.svelte to apply the color change.
Is there a reactive way to update elements on the hosted page immediately?
__layout.svelte:
<script>
let color = "green";
function onClick(e) {
color = "red";
}
</script>
<button on:click={onClick}>Red</button>
<slot color={color}></slot>
index.svelte:
<script>
export let color = "blue";
</script>
<div class="box" style="background-color:{color}"></div>
<style>
.box {
width: 100px;
height: 100px;
margin: 10px;
}
</style>
Code above can be found here:
Upvotes: 3
Views: 2098
Reputation: 16411
You can create a store in the load
function and pass this on one side to the layout and on the other side place in stuff
.
<!-- __layout.svelte -->
<script context="module">
import { writable } from 'svelte/store';
export async function load() {
const color = writable('green');
return {
props: {
color
},
stuff: {
color
}
};
}
</script>
<script>
export let color;
function onClick(e) {
$color = 'red';
}
</script>
<button on:click={onClick}>Red</button>
<slot />
Then in the load
function of the page itself, you grab this store from stuff
and pass it on with the props.
<script context="module">
export async function load({ stuff }) {
return {
props: {
color: stuff.color
}
};
}
</script>
<script>
export let color;
</script>
<div class="box" style="background-color:{$color}" />
<style>
.box {
width: 100px;
height: 100px;
margin: 10px;
}
</style>
Now you have reactivity!
a note on shared state and global stores
This works fine as described above, if you have a store that 'lives' outside of the load function this is considered shared state and will be common among all users, so be carefull with this.
<script context="module">
import myStore from './myStore.js';
export async function load() {
myStore.set(something_sensitive); everyone has access to this now!!
}
</script>
Upvotes: 2