Svelte State
Because I'm not really doing daily updates here anymore, I'm trying to take notes with a focus on a specific topic that I'm wrapping my head around so that I can share my findings here when I reach some sort of conclusion. With that in mind, I wanted to tackle one of the most fundamental and unique features of Svelte 5 early in this project, managing state with runes. To reach that end, I started with an idea of how I wanted a couple of components to work, I figured out a quick and dirty implementation, and then I took a step back and thought about how I could improve the process.
My goal was simple enough: I have two components, both used on my app's main page. One component is a popup that allows the user to create a new object in the database, and the other component is a button that makes the object creation popup appear. Basically I needed a way of managing the visibility of the popup so that I could toggle it open with the button and toggle it closed from a couple places on the popup itself.
My first thought was to create a state variable within the app's main page, and then pass it to each child component as a prop. I got this idea to work, but it came with a few downsides.
- Data flowing from children back up to the parent is a bit of an antipattern in component based frontend development
- I have to pass the same variable to multiple components, which does not scale well
- I had to use the $bindable rune in addition to the $state rune to actually accomplish this. $bindable is a neat element that indicates data should be synced (or bound) between the parent and child, but the aforelinked docs indicate that it should be used sparingly
So, even though the app worked as expected, I wasn't very happy with the first implementation. After a little more googling and doc reading I came across a pattern that seemed a lot more in line with what I wanted to do. I eneded up creating a new [placeholder]State.svelte.ts
file that exported a single $state variable containing an object. The entirety of the file is below. From here, I was able to import that object into the exact files where I needed to access its fields. There were a few immediate benefits to this approach.
- Didn't need to worry about state being present in the main page where it was not necessary
- Easier access to state properties in the exact places where I needed them
- Got rid of the $bindable runes, making the code easier to follow
This approach was a lot more satisfying to me and I think is a lot more in line with best practices for Svelte development. Despite this, I still have a few questions/areas for improvement here.
- Right now the file containing my state object is very plain. Can I put functions in here?
- What is stopping me from creating one giant state object? On the flip side, how granular should I keep my state objects?
With all this said, I am not an experienced Svelte developer. Nothing here should be taken as gospel, or even really as advice. I'm sure I'll discover that several statements I made here were wrong as I go further in this project. But so far, it's been a lot of fun to learn and I hope documenting my journey will be helpful to someone in the future!