Reputation: 259
I want to rerender "Body" (my svelte component) whenever "view.current" changes so it renders the corresponding .svelte view/component:
App.svelte
<script>
import Header from "./components/Header.svelte";
import Footer from "./components/Footer.svelte";
import Body from "./components/Body.svelte";
import Login from "./views/Login.svelte";
import Dashboard from "./views/Dashboard.svelte";
import { view } from "./store";
</script>
<Header />
<Body>
{#if view.current === view.login}
<Login />
{:else if view.current === view.dashboard}
<Dashboard />
{/if}
</Body>
<Footer />
In "Body.svelte" i just have a slot that gets styled
Body.svelte
<div class="container">
<div class="content">
<slot></slot>
</div>
</div>
<style>
.container {
padding: 1em;
display: flex;
}
.content {
margin: auto;
}
</style>
In Login.svelte (and other svelte components) i want to change "view.current":
Login.svelte
<script>
import { view } from "../store";
function handleLoginClick() {
view.current = view.dashboard;
}
</script>
<button type="button" on:click={handleLoginClick} class="btn btn-primary btn-lg login-btn">Login</button>
<style>
.login-btn {
display: block;
margin: auto;
}
</style>
store.js
const user = {
username: "",
fullname: "",
role: null,
isLoggedIn: false
};
const view = {
login: 1,
dashboard: 2,
current: 1
};
export {
user,
view
}
The value of "view.current" changes as expected, however "Body" does not update/rerender. So it always shows the login.svelte no matter to what "view.current" has been set. Is there a quick and easy way to make "Body" reactive to "view.current" so that it rerenders so that the if/else-block in "App.svelte" get's reevaluated?
Upvotes: 3
Views: 3817
Reputation: 16411
Importing a regular variable like that in a component creates a local copy of said variable. The view
you are referring to in the Login is not shared with the one in App, so the changes are not reflected there.
The "Svelte-way" of sharing state like that accross components is to use a store.
In your setup that would mean you define view as a store first:
import { writable } from 'svelte/store'
const view = writable({
login: 1,
dashboard: 2,
current: 1
});
In the components themselves you have to prefix the store with $
<script>
function handleLoginClick() {
$view.current = $view.dashboard;
}
</script>
{#if $view.current === $view.login}
<Login />
{:else if $view.current === $view.dashboard}
<Dashboard />
{/if}
Upvotes: 8