--- title: State management --- Svelte components have built-in state management via the `get` and `set` methods. But as your application grows beyond a certain size, you may find that passing data between components becomes laborious. For example, you might have an `` component inside a `` component that allows the user to control the behaviour of a `` component. You could use bindings or events to 'send' information up from `` through `` to a common ancestor — say `` — which would then have the responsibility of sending it back down to ``. But that's cumbersome, especially if you decide you want to break `` up into a set of smaller components. Instead, a popular solution to this problem is to use a *global store* of data that cuts across your component hierarchy. React has [Redux](https://redux.js.org/) and [MobX](https://mobx.js.org/index.html) (though these libraries can be used anywhere, including with Svelte), and Vue has [Vuex](https://vuex.vuejs.org/en/). Svelte has `Store`. `Store` can be used in any JavaScript app, but it's particularly well-suited to Svelte apps. ### The basics Import `Store` from `svelte/store.js` (remember to include the curly braces, as it's a *named import*), then create a new store with some (optional) data: ```js import { Store } from 'svelte/store.js'; const store = new Store({ name: 'world' }); ``` Each instance of `Store` has `get`, `set`, `on` and `fire` methods that behave identically to their counterparts on a Svelte component: ```js const { name } = store.get(); // 'world' store.on('state', ({ current, changed, previous }) => { console.log(`hello ${current.name}`); }); store.set({ name: 'everybody' }); // 'hello everybody' ``` ### Creating components with stores Let's adapt our [very first example](docs#understanding-svelte-components): ```html

Hello {$name}!

``` ```html

It's nice to see you, {$name}

``` ```js /* { filename: 'main.js' } */ import App from './App.html'; import { Store } from 'svelte/store.js'; const store = new Store({ name: 'world' }); const app = new App({ target: document.querySelector('main'), store }); window.store = store; // useful for debugging! ``` There are three important things to notice: * We're passing `store` to `new App(...)` instead of `data` * The template refers to `$name` instead of `name`. The `$` prefix tells Svelte that `name` is a *store property* * Because `` is a child of ``, it also has access to the store. Without it, `` would have to pass the `name` property down as a component property (``) Components that depend on store properties will re-render whenever they change. ### Declarative stores As an alternative to adding the `store` option when instantiating, the component itself can declare a dependency on a store: ```html

Hello {$name}!

``` ```html

It's nice to see you, {$name}

``` ```js /* { filename: 'store.js' } */ import { Store } from 'svelte/store.js'; export default new Store({ name: 'world' }); ``` Note that the `store` option is a function that *returns* a store, rather than the store itself — this provides greater flexibility. ### Computed store properties Just like components, stores can have computed properties: ```js store = new Store({ width: 10, height: 10, depth: 10, density: 3 }); store.compute( 'volume', ['width', 'height', 'depth'], (width, height, depth) => width * height * depth ); store.get().volume; // 1000 store.set({ width: 20 }); store.get().volume; // 2000 store.compute( 'mass', ['volume', 'density'], (volume, density) => volume * density ); store.get().mass; // 6000 ``` The first argument is the name of the computed property. The second is an array of *dependencies* — these can be data properties or other computed properties. The third argument is a function that recomputes the value whenever the dependencies change. A component that was connected to this store could reference `{$volume}` and `{$mass}`, just like any other store property. ### Accessing the store inside components Each component gets a reference to `this.store`. This allows you to attach behaviours in `oncreate`... ```html ``` ...or call store methods in your event handlers, using the same `$` prefix as data properties: ```html ``` ### Custom store methods `Store` doesn't have a concept of *actions* or *commits*, like Redux and Vuex. Instead, state is always updated with `store.set(...)`. You can implement custom logic by subclassing `Store`: ```js class TodoStore extends Store { addTodo(description) { const todo = { id: generateUniqueId(), done: false, description }; const todos = this.get().todos.concat(todo); this.set({ todos }); } toggleTodo(id) { const todos = this.get().todos.map(todo => { if (todo.id === id) { return { id, done: !todo.done, description: todo.description }; } return todo; }); this.set({ todos }); } } const store = new TodoStore({ todos: [] }); store.addTodo('Finish writing this documentation'); ``` Methods can update the store asynchronously: ```js class NasdaqTracker extends Store { async fetchStockPrices(ticker) { const token = this.token = {}; const prices = await fetch(`/api/prices/${ticker}`).then(r => r.json()); if (token !== this.token) return; // invalidated by subsequent request this.set({ prices }); } } const store = new NasdaqTracker(); store.fetchStockPrices('AMZN'); ``` You can call these methods in your components, just like the built-in methods: ```html ``` ### Store bindings You can bind to store values just like you bind to component values — just add the `$` prefix: ```html ``` ### Using store properties in computed properties Just as in templates, you can access store properties in component computed properties by prefixing them with `$`: ```html {#if isVisible}
{todo.description}
{/if} ``` ### Built-in optimisations The Svelte compiler knows which store properties your components are interested in (because of the `$` prefix), and writes code that only listens for changes to those properties. Because of that, you needn't worry about having many properties on your store, even ones that update frequently — components that don't use them will be unaffected.