Svelte Custom Stores for React Developers: Part 2

This is part 2 of a walkthrough of me learning how to use custom data stores in Svelte. To see the initial setup, please read Part 1

Now that I have set up a Svelte custom data store, and then used that store to display a list of animal HTML representations of the data from a local API, I want to make sure that my store is truly maintaining its own state, and that it is available to multiple components.

Mini Animal List

I decided to create another component that create a list of animal HTML representations, but each one is very small, and uses a cute puppy emoji 🐶.

src/animals/MiniAnimalList.svelte

<script>
  import { animals, getAnimals } from "./AnimalStore.js";
  getAnimals()
</script>

<article class="animals">
  {#each $animals as animal}
    <section>🐶 { animal.name }</section>
  {/each}
</article>

Showing Both Lists

Now to update the main Kennel component to render both lists.

<main>
  <h1>Nashville Kennels</h1>

  <div class="splitScreen">
    <AnimalList />
    <AnimalMiniList />
  </div>
</main>

And after a the page auto-refreshes, here's what I see.

Reacting to Changes

Ok, so both components rendered their own HTML representatios of the data, but I have to do one more check to make sure that they both reference the same data and aren't working with their own copies of the array.

I decide to add a button to the main animal list component that, when clicked, performs a POST to the API to add a test animal. If this all works the way it's supposed to, the mini animal list should immediately re-render with the new animal.

POST Method in the Store

Time to add a function to the data store that will perform a POST fetch to create a new animal in the API.

src/animals/AnimalStore.js

... existing code ...

export const createAnimal = async (animal) => {
    const response = await fetch("http://localhost:8088/animals", {
        "method": "POST",
        "headers": {
            "Content-Type": "application/json"
        },
        "body": JSON.stringify(animal)
    });
    const new_animal = await response.json();

    if (response.ok) {
        await getAnimals()
    }
}

Creating Animals in the List

Now to update the animal list component with a simple test animal object, and a button for the user to click to initiate the entire process.

src/animals/AnimalList.svelte

<script>
  // Updated to import new `createAnimal()` function
  import { animals, getAnimals, createAnimal } from "./AnimalStore.js";
  getAnimals();

  // Simple animal object in component state
  const test_animal = {
    name: "Test",
    breed: "Jack Russell"
  };
</script>

<button on:click={() => createAnimal(test_animal)}>
  Create Test Animal
</button>

<article class="animals">
  {#each $animals as animal}
    <section class="animal">
      <div class="animal--name">
        <h2>{animal.name}</h2>
      </div>
      <div class="animal--breed">{animal.breed}</div>
    </section>
  {/each}
</article>

Ok, fingers crossed. Let's see if both components update immediately on state change.

It Works!

Well, that was pretty cool. Now both components are interacting with the same store and staying in sync whenever the data changes.

I hope you found this quick walkthrough helpful!