Svelte logo

Svelte by Example: State

Svelte uses let variables to hold local component state.

In this example, we'll create an AddTodo component to add new todos.

Data is reactive and can be used as state.

Reassigning a variable will invalidate the component and trigger an update. After an update is triggered, Svelte will update the DOM to reflect the new state.

AddTodo.svelte
<script>
  import { createEventDispatcher } from 'svelte';

  const dispatch = createEventDispatcher();

  let task = '';

  function handleInput(event) {
    task = event.target.value;
  }

  function submit() {
    dispatch('add', {
      task,
      completed: false,
    });
  }
</script>

<p>
  <input
    type="text"
    value={task}
    on:input={handleInput}
  >
  <button on:click={submit}>
    Add
  </button>
</p>

To update an object or an array, it must be reassigned.

TodoList.svelte
<script>
  import Todo from './Todo.svelte';
  import AddTodo from './AddTodo.svelte';

  let todos = [];

  function addTodo(event) {
    todos = todos.concat([event.detail])
  }
</script>

{#each todos as todo}
  <Todo {...todo} />
{/each}

<AddTodo on:add={addTodo} />

A more succinct way to bind state to an element or a component is with Svelte's bind: attribute prefix.

CreateTodo.svelte
<script>
  let task = '';
</script>

<input type="text" bind:value={task}>

Reactivity Rules

Reassigning an array will trigger a change.

Mutating an array and reassigning it will trigger a change.

Mutating an array will not trigger a change.

Reassigning an object will trigger a change.

Mutating an object and reassigning it will trigger a change.

Mutating an object will not trigger a change.

function addTodo(task) {
  todos = todos.concat([{ task, completed: false }]);
}

function addTodo(task) {
  todos = [...todos, { task, completed: false }];
}

function addTodo(task) {
  todos.push({ task, completed: false });
  todos = todos;
}

function addTodo(task) {
  // Does not work!
  todos.push({ task, completed: false });
}
function completeTodo() {
  task = { ...task, completed: true };
}

function completeTodo() {
  task.completed = true;
  task = task;
}

function completeTodo() {
  // Does not work!
  task.completed = true;
}