All About State Management In Svelte
Published: 2024-05-02 06:11:43

by [Felicia Oke](https://blog.openreplay.com/authors/felicia-oke)




<blockquote><em>
In modern web development, managing application state effectively is not just a best practice but a fundamental necessity that determines how data is shared within the application components. State management is crucial in any interactive application, as it involves tracking and handling its current state data. In this tutorial, you will learn how to manage your Svelte application's states effectively.
</em></blockquote>



<div style="background-color:#efefef; border-radius:8px; padding:10px; display:block;">
<hr/>
<h3><em>Session Replay for Developers</em></h3> 
<p><em>Uncover frustrations, understand bugs and fix slowdowns like never before with <strong><a href="https://github.com/openreplay/openreplay" target="_blank">OpenReplay</a></strong> — an open-source session replay suite for developers. It can be <strong>self-hosted</strong> in minutes, giving you complete control over your customer data.</em></p>
<img alt="OpenReplay" style="margin-top:5px; margin-bottom:5px;" width="768" height="400" src="https://raw.githubusercontent.com/openreplay/openreplay/main/static/openreplay-git-hero.svg" class="astro-UXNKDZ4E" loading="lazy" decoding="async">
<p><em>Happy debugging! <a href="https://openreplay.com" target="_blank">Try using OpenReplay today.</a></em><p>
<hr/>
</div>





There are numerous benefits to effectively managing your application state, including the following:

- **Improved Performance**: Efficient state management can optimize rendering and minimize unnecessary re-renders, thereby enhancing the application's overall performance.

- **Enhanced Scalability**: A well-organized state management approach facilitates the application's scalability, enabling it to easily handle increasing complexity and user interactions.

- **Maintainability**: Effective state management promotes clean and maintainable code by segregating concerns and using a structured approach to handle application data, making it easier to debug and maintain over time.

- **Reusable Components**: Through effective state management, components can be designed to be more reusable as they become decoupled from specific data dependencies, allowing for greater flexibility and versatility in application development.

## Creating a New Svelte Project
Let's get started by creating a new Svelte project. To do so, open your terminal, navigate to your working directory, and run the following commands.
```bash
npx degit sveltejs/template svelte-project
cd svelte-project
npm install
```
## Using Svelte Props and Context API
In Svelte applications, props and context API can be used to manage state data flow. Let’s explore how we can effectively use props and context API to manage our application states.
### Passing State Down to Child Components with Props
Props are values passed from a parent component to a child component. They allow us to pass data down the component tree, enabling parent components to communicate with their children.

Let's consider, for example, that we want to accept a username as an input in our main component and send the input value to a child component using a prop. To achieve this, create a child component file named `ChildComponent.svelte` in your project's `src` folder and add the following code.
```html
<script>
  export let username;
</script>
<div>
  <h2>Child Component</h2>
  <h3>User Info</h3>
  <p>Username: {username}</p>
</div>
```
The `export` statement is used in the code above to access the prop value passed to the current component. We then display the username prop using `{username}` within the user interface.

Next, in your main component, you can pass the `username` prop data to the `ChildComponent.svelte` component by adding the following code to the `App.svelte` component.
```html
<script>
  import ChildComponent from "./ChildComponent.svelte";
  let username = "";
  function handleChange(event) {
    username = event.target.value;
  }
</script>
<body>
  <div>
    <h1>Parent Component</h1>
    <input
      type="text"
      placeholder="Enter your username"
      on:input="{handleChange}"
    />
    <ChildComponent username="{username}" />
  </div>
</body>
<style>
  body {
    background-color: darkcyan;
  }
</style>
```
From the code above, we:
- Import the `ChildComponent.svelte` component and declare a reactive variable named username, initializing it with an empty string.
- Define the `handleChange()` function, which triggers whenever the input field's value changes, updating the `username` variable.
- Create the input field and render the child component.

Now, you should have the child component accessing the `username` prop, as shown in the GIF image below.
![oke](https://blog.openreplay.com/images/all-about-state-management-in-svelte/images/image1.gif)
That's how you can use props to manage your application data. But what if you want to manage more complex application data? That's where the Context API comes in.
### ⁠Using Context API to Share State Across Components
[Context API](https://learn.svelte.dev/tutorial/context-api) allows us to share application state data between components without having to pass it down through props at every level of the component tree.

With the Context API, we create a context object in a parent component, enabling the sharing of complex application state data. This context can then be accessed in any of its descendant components. This approach provides a more elegant way to manage and share global state or other shared data within our application.

Let's demonstrate how we can effectively pass user information such as full name, user name, email, and gender from the main component to the child component (`ChildComponent.svelte`) using Svelte's built-in Context API. Add the following code to the `App.svelte` file to do that.

```html
<!-- App.svelte-->
<script>
  import { setContext } from "svelte";
  import ChildComponent from "./ChildComponent.svelte";
  let user = {
    fullName: "Felicia Oke",
    username: "Felicia123",
    email: "Felicia123@gmail.com",
    gender: "Female",
  };
  setContext("userInfo", user);
</script>
<div>
  <h1>Parent Component</h1>
  <ChildComponent />
</div>
```
From the code above, we:
- Import the `setContext` function from Svelte which is used to set the application data globally.
- Create a user object containing information such as fullname, username, email, and gender.
- The application state data is shared using the `setContext()` method, which accepts `userInfo` as the key name and `user` as the state object.
-  The `<ChildComponent />` template is then used to render the `ChildComponent`.

Now, let's access the user state data inside the `ChildComponent.svelte` file. To do so, open `ChildComponent.svelte` and replace its code with the following:
```html
<script>
  import { getContext } from "svelte";
  let user = getContext("userInfo");
</script>
<div>
  <h2>Child Component</h2>
  <h3>User Info</h3>
  <p>Fullname: {user.fullName}</p>
  <p>Username: {user.username}</p>
  <p>Email: {user.email}</p>
  <p>Gender: {user.gender}</p>
</div>
```
In the code above, we import `getContext` from Svelte to fetch user data from the main component, and then we display the user’s information on the user interface.

Reload the application in your browser. You should have the following output, as shown in the image below:
![Screenshot 2024-04-04 at 17.22.33](https://blog.openreplay.com/images/all-about-state-management-in-svelte/images/image2.png)

<CTA_Middle_Frameworks />



## Using Svelte Stores

[Svelte store](https://svelte.dev/docs/svelte-store)s are a feature in the Svelte framework for managing and sharing reactive state across components in an application. They provide a straightforward way to handle global state and facilitate communication between components without the need for complex state management libraries.

By leveraging Svelte stores, we can achieve efficient and maintainable state management without needing external libraries, prop drilling, or complex state management patterns. This allows us to easily keep track of changes in the application data.

Let's explore the types of Svelte Stores and how we can effectively use them to manage our application state.
### Writable
[Writable](https://learn.svelte.dev/tutorial/writable-stores) store in Svelte is a type of store that holds a mutable state. It allows us to store and update data that can be shared across multiple components in our application. Writable stores are particularly useful for managing states that need to be modified from different parts of our application.

Using writable stores involves creating a writable store, updating its value, and subscribing to its component changes. To use writable stores, create a JavaScript file named `store.js` and add the following code:
```javascript
import writable from 'svelte/store'
export const WeekDay = writable('sunday')
```
We can access the store value in any of our application components by adding the following code.
```html
<script>
  import { writable } from "svelte/store";
</script>
<p>The current count is {$WeekDay}</p>
```
We can update the value of the writable store using its set method, as used in the code below.
```javascript
WeekDay.set('Friday');
```
The above code will change the value of `WeekDay` to `Friday` from anywhere in our application components.
### Readable
A [Readable store](https://svelte.dev/examples/readable-stores) is a type of store that holds an immutable state. Unlike writable stores, which allow you to update their values, readable stores are read-only. Once initialized, their value cannot be directly modified from outside the store. Below is an example of effectively managing your application state using a Readable store.

Inside the `src` folder, create a file named `store.js` and add the following code:
```javascript
// user.js
import { readable } from 'svelte/store'
export const user = readable({ name: 'John', age: 30 })
```
To access the Readable store value in the application component, add the following code to the component:
```html
<script>
  import { user } from "./user.js";
</script>
<p>The user's name is {$user.name} and the age is {$user.age}.</p>
```
### Derived
[Derived stores](https://svelte.dev/examples/derived-stores) enable the creation of reactive data stores computed from existing stores. They're designed to update automatically based on changes to the base stores they depend on, making them a powerful tool for managing and manipulating data in Svelte applications.

Open the `user.js` file and add the following code to it: 
```javascript
export const formattedUser = derived(user, ($user) => {
  return {
    fullName: $user.name,
    birthYear: new Date().getFullYear() - $user.age,
  };
});
```
In this example, `formattedUser` is a derived store created from the user store. It computes a new value based on the data in the user store.
Now, you can use `formattedUser` in your Svelte components just like any other store. To do that, update the `App.svelte` code with the following: 
```html
<script>
  import { formattedUser } from "./store.js";
  let userInformation;
  formattedUser.subscribe((value) => {
    userInformation = value;
  });
</script>
<div>
  <p>Full Name: {userInformation.fullName}</p>
  <p>Birth Year: {userInformation.birthYear}</p>
</div>
```
This way, whenever the data in the user store changes, the `formattedUser` derived store will automatically update its value, and any components subscribed to it will reactively re-render to reflect the changes.
### Building a Todo-list with Svelte Store
To put our Svelte Store to practical use, let’s create a todo app and manage the application state using Svelte Store. Follow the steps below to create the todo list.

Create a `todos.js` file to define the Svelte store for managing todo and add the code below to it:
```javascript
import { writable } from "svelte/store";
export const todos = writable([
  { id: 1, text: "Learn Svelte state management", completed: false },
  { id: 2, text: "Build a Todo-list with state management", completed: false },
]);
```
Next, create Svelte components `TodoList.svelte`, `TodoItem.svelte`, and `AddTodo.svelte` to interact with and display the todos.

Inside the `TodoList.svelte` file, add the following code:
```html
<script>
  import { todos } from "./todos.js";
  import TodoItem from "./TodoItem.svelte";
  $: todoList = $todos;
</script>
<div>
  <h1>Todo List</h1>
  {#each todoList as todo}
  <TodoItem {todo} />
  {/each}
</div>
```
To mark a todo item as done or not, add the following code to the `TodoItem.svelte` component:
```html
<script>
  export let todo;
</script>
<div>
  <input type="checkbox" bind:checked="{todo.completed}" />
  <span
    style="
      text-decoration: {
        todo.completed? 'line-through' : &quot;none&quot;;
      }
    "
    >{todo.text}</span>
</div>
```
To add a new item to the todo list, add the following code to the `AddTodo.svelte` component:
```html
<script>
  import { todos } from "./todos.js";
  let newTodo = "";
  function addTodo() {
    todos.update((existingTodos) => [
      ...existingTodos,
      { id: Date.now(), text: newTodo, completed: false },
    ]);
    newTodo = "";
  }
</script>
<div>
  <input type="text" bind:value="{newTodo}" placeholder="Enter new todo" />
  <button on:click="{addTodo}">Add</button>
</div>
```
Now, to connect all the todo list components together, replace the code in `App.svelte` with the following:
```html
<script>
  import TodoList from "./TodoList.svelte";
  import AddTodo from "./AddTodo.svelte";
</script>
<body>
  <main>
    <TodoList />
    <AddTodo />
  </main>
</body>

<style>
  body {
    background-color: darkcyan;
  }
  main {
    padding: 20px;
    margin-left: 30%;
  }
</style>
```
Save your code and open http://localhost:8080/ in your browser. You should see the output in the GIF image below.
![todo](https://blog.openreplay.com/images/all-about-state-management-in-svelte/images/image3.gif)

## Conclusion
State management plays a crucial role in application development, enabling the tracking of data changes and effective management of the application state. In Svelte, a lightweight framework, numerous techniques can be employed to manage the state efficiently.

In this tutorial, we explored various approaches to managing the Svelte application state and demonstrated how to effectively manage a todo app's state to improve application performance and maintenance.