November 20th, 2024 × #javascript#state-management#front-end
Manage State in JavaScript Like a Pro!
This episode covers different approaches to state management in JavaScript, including reducer-based, mutation-based and atom-based state. Buzzwords like reactive state, stores, immutability vs mutability, state updaters and more are also explained.
Transcript
Wes Bos
Welcome to SyntaxToday. We got a show for you on state management in JavaScript. This is kind of an interesting one because we all have to manage state in our application, and there are many different libraries out there. There's many different approaches.
Wes Bos
You're hearing all these words like signals, reducers, actions, immutable reactivity, state machine, global, local.
Different state management approaches and buzzwords
Wes Bos
If you're using React, you're using a different framework. You're using vanilla JavaScript. There's all kinds of things to sort of consider. So we're going to do a show today that will sort of break down the different state management approaches, different ways to hold state, things that you should consider JS well as go through some of the more popular options in the state management world right now. My name is Wes Bos. I am a developer from Canada with me JS always, Scott. How are you doing, Scott? I'm doing good, man. Just chilling.
Scott Tolinski
Actually, literally chilling. It's cold here in Colorado. So yeah. Oh, man. We
Wes Bos
have oh, yeah. We had opened the windows last night. It's like like summer weather still here, which is wild Oh, yeah. Considering it was snowing this time last year.
Scott Tolinski
Wes we have the classic, super cold at night, super hot during the day flow going on right now. Oh, I meant that. Yeah. Open the windows. Let me freeze. Yep. And then open the windows. Let me cook during the day. That's that's right.
Wes Bos
Real quick. Let's talk about something that Century is behind. It's the Open Source Pledge Scott. So they just rolled this out. Basically, having encouraging other companies to pledge part of their profits, part of the revenue to open source. So the Open Source Pledge Scott is a really cool initiative. You can go to it and see there are tons of companies on here that are paying actual maintainers. So you could take a look at the list. Century, a 135 Deno. They are contributing $3,704 per developer back towards open source. And there's a huge list of companies that have sort of taken the pledge. I mean, like, you know what? We use open source to run our business.
Wes Bos
It's probably time that we give some of that money back to open source, may make sure that we have a healthy community. So check it out. And, if you have a boss or you are a boss, I encourage you to sign up for it as well. Opensourcepledge.com.
Scott Tolinski
Yeah. Hey. Let's let's actually even shout out. Maybe we should shout out some of these companies that are are taking this pledge. One of which that I've been following for a little while is Emerge Tools.
Scott Tolinski
Do you follow Emerge Tools on Twitter? No.
Scott Tolinski
They're a good follow. They break down apps. Oh, yes. And they show, you know, what the what libraries apps are using, and and these are all, like, Bos apps and production apps. And so they'll just open up the FedEx app and and talk about, like, what percentage of the app is localization and fonts and whatever. And it's it's always fascinating whenever one of these comes up. It's like they they have, like, kind of like a like a daisy disk graph or dependencies for apps and kind of talk about where the size is going. So a shout out to Emerge, tools on, Twitter specifically, I think JS where I follow them or get the the most information from them. But cool of them see them on the, the open source pledge. Alright. Let's talk about state. So what is state? State is a representation.
What is state in an application
Wes Bos
It's data that represents the current condition of your application, right, the current state of your application, and it determines things like the behavior, how your application acts, as well as the appearance. What does it actually look like? So I thought we're first gonna start off with some common words that you're going to hear us talk about. So just go through some of the buzzwords, then we'll talk about the sort of the 3 big approaches to state management, Wes the whole state, global Vercel component state, and then we'll go into state libraries that you could possibly be using. So first one we have here is, reactive state. This is a word that you're gonna hear quite a bit, and what that essentially means is that when you're building an application, you take your state, your data, and you put it into your templates.
Wes Bos
A reactive state will update those templates when that state updates. Right? A very simple example, you have a counter. You increment that value by 1. Wherever that variable is that used in your templates will update itself.
Reactive state updates templates automatically
Scott Tolinski
Yes. Next one is store, and the store is just a word that people often use for a place where you put your state. I mean, people sometimes just call it a state. Sometimes people call it a store, a data store. Basically, a store is someplace that your data lives. Yes. And a store often we're gonna talk about the different types of it, but a store will also often include
Wes Bos
the logic as to how that store can be interacted with. Right? So it'll include a set of functions for updating, deleting, modifying the data in the store. Warp. We also have immutable versus mutable.
Wes Bos
What this means is that can you directly reach into your state and update it directly, or does it is it updated via a set of updater functions? So immutability is the idea that you should not just simply like, let's say you have a object called Wes, and it has an age of, I forget how old I am, 37, 36, something like that. Yeah.
Wes Bos
And you wanna increase the age, you don't for for in a mutable state, you would simply just say Wes Scott age plus plus or west dot age equals 100. A mutable state would have a function that takes in Wes and returns a new instance of Wes so that you're not actually going into the the value in updating it.
Scott Tolinski
Yeah. Well, it'd be like if we were cloning Wes. Like, if we we put Wes into a cloner and transported him somewhere else, disassemble all those atoms and create a new version of him with changes.
Scott Tolinski
Next one is state updaters. These are functions that update state. Now this can be done very simply with just a a simple, like, Scott set state or a set Scott. And this can be done with a dot set. But this can also be done in a much more complex way of something like reducers, where you're taking in the old values, you're taking in the new values, and you're manually merging them yourself.
Wes Bos
A signal is we're not gonna go too deep into signals on this because we can do a whole show on it Wes have, and we probably should do another one. But, a signal is a way to manage state that has both a getter, which is how you consume the state, and a setter, that you use to update it. And then there's this idea that if you want to listen for when that state has changed, it's called an effect.
Wes Bos
So that's another thing you're gonna hear JS basically just like watching for changes on that state is often called an effect. Yes. Next Node is observables, which GitHub observables,
Scott Tolinski
you know, in the observer pattern in general is just you can think of you're observing something. You're you're listening for something. You're waiting for something to change. So with observables, you're being able to listen for changes on them and respond accordingly.
Wes Bos
Another, kind of saying that you're gonna hear is UI is a function of Scott, and what that means is that in order to get the UI for your application, it has to take in the data, meaning that you can derive any UI of your, application based on its actual state. And as you get into more and more complex applications, for example, TL draw is is one of my favorite applications. This is like a little a not a little. It's a it's a drawing application, like a whiteboard. Right? And there's real time in there, and you can, like, you can select on something you've you've you've drawn. You can right click.
Wes Bos
And the thing that always gets me is that when you when you right click on one of the pieces in the application, there's a whole context menu.
Wes Bos
And the parts of that context menu depend on what you have selected, what cup maybe what color it JS, if you've selected multiple things. And I often think about how complex that simple right click is on on tldraw because there are so many decisions that need to happen before they can simply display the the actual options that are there. And I always think about that as being a very good example of the UI of the right click takes in the entire world of what you've you've clicked and maybe even stuff behind it, and it gives you a set of options to arrange them and copy paste them, move them around, select them, delete them, etcetera.
Scott Tolinski
Word. Alright. Next 1 is a state machine. And now a state machine is an interesting way of working with state Wes any individual state has basically, several options that it can do, but only do from that state. So if you think about, like, you have a piece of state, perhaps that state is a string. A lot of times when we're working state with state, we'll just call a set state and update that string to anything. But when you're working in a state machine, it doesn't quite work like that. Wes have a state machine. You have a piece of state. There's only a a defined path of places it can go from that. So, basically, you have your Scott, and then you tell it which path to go next. And then now it's in that state, and it can only then go from other places of state. This kind of is at odds with Wes people use things like Boolean variables for things like, is open or something like that. You're more or less like, alright. The status of this thing is now it is open. And therefore, that brings along a lot of other properties. And from open, where can this go? Well, it can only go to closed from open, you know, from open to closed. And then from there, you you can build off this whole tree of a a state machine.
Wes Bos
Yes. It's a lot more complex. However, if you've ever been in an application where you think, I shouldn't be able to do that when this thing happens Totally. Or, like, if you have, like, a 1,000 booleans or, like, alright. I'm going to display the right click, and then you have a 1,000 if statements. So, well, if if there's this is set, but they also have selected this. Or or if you are currently in this mode, but you're allowed to do this, holy hell. That can get very, very complicated very quickly.
Wes Bos
So I've not had to use a state machine in applications that I have built, but I have talked to lots of people that build much more complex applications, lots of desktop software.
Wes Bos
We had Andrew on who works at Descript, and he says that is very complex app, and that's a massive state machine.
Scott Tolinski
Yeah. I tend to work with all of my state that is complex as even most of my state, I'm gonna just say in general, as a state machine lite where Yes. I'm not I I'm, like, refusing to use Boolean values for state in that sort of way, and I am more or less not not adhering to something as strict as some of these libraries like x state, but still utilizing some of the the principles The ideas behind it.
Wes Bos
Binding Scott, this is an idea of being able to update state when you are changing it. So, like, for example, if you have a piece of state, which JS, like, what's your Node. Right? And then then then you also have that state in an input.
Wes Bos
If you change that input, then that state is often, needs to be bound to back to the state so that when you change the input, the that state is also updated. I feel like I'm saying state a lot.
Scott Tolinski
Yeah. I feel like that's an unfortunate thing that's going to happen in this. It's really hard to to even, like, discuss state without saying the word state.
Scott Tolinski
Another one is is global versus local Scott. You could think of this as global as state that your entire application needs to access, where local Wes state that only 1 specific, even, like, chunk or component needs to access.
Wes Bos
Computed, derived, or selector state. This is the idea that your state is actual data. However, if you want to display that data in a a different way or if you want to generate state based off of that, For example, if you have, a price for an item in your state, right, or your cart might be 5,000 and 1.
Wes Bos
But when you actually want to display that value, you might use a derived state, which will then go ahead and and format it. So there also could be a state that needs to be, like, multiplied by 2, and then you need to listen for when that state is higher than a certain value. So it's not simply just how to format it, but it it could be a piece of state that depends on some other state and needs to be recalculated every single time that it is updated.
Wes Bos
Word. Alright. So let's talk about the kind of 3 ways to to attack state. You have reducer based Scott. You have mutation based state, and you have atom based state. So reducer based Scott, and these are all handy in different aspects of your application and sort of how you like to approach it. So a reducer based state is is is like Redux. Redux is probably the most popular reducer based state. However, there is is several of them out there. And then the way that a reducer based state works is that you you have a store, which is it has your data inside of it, and then you have something that are called actions. And actions are ways that you can update your state. They describe what will happen along with any arguments. So, for example, you might want to, increment a number by 1. You might want to you might have a an array of comments, and you wanna add additional comment to that. You might want to delete an item from a list of posts. So an action would be something like increment, add comment, or remove thing.
Reducer based state is immutable
Wes Bos
Whereas, you have a reducer.
Wes Bos
The reducer is the actual function. That's the actual business logic as to how do I increment it? How do I add a comment? How do I remove an item from that array? The reducer takes in your current state, does the work, and then out the other end returns you back the the modified or updated state. So that's the the whole idea there is that your state is immutable, meaning that you you take your old state, and then you return a new state from that. And the benefit to that immutability is you can, have some really cool dev tools where you can sort of scrub back and say, oh, what happens if I don't do this specific action? You can see what actions have been taken, and you can sort of time step through that, which which can be really handy in complex applications.
Scott Tolinski
Yeah. Totally.
Scott Tolinski
There's also the word dispatch Wes with a dispatch, it's basically how you trigger or fire that action. So we mentioned that the actions are the thing that you're doing. The reducer is the work itself, and dispatching is the firing of that action.
Scott Tolinski
There's also subscribe where you're listing for the changes, and you can use it to update the UI. I found that this flow when I did not understand or use Redux, I found this flow to be daunting from a viewpoint. Like, looking at it, you'd say Yeah. Man, that's a whole lot to update a variable. And I feel like a lot of people felt that way too. However, once I actually used Redux, I kinda gained a little bit of a fondness for it, which maybe, you know, it's like Stockholm syndrome with, like, React in general, where, like, at first, you're like, ah, this is all too complex. And then later, you're like, well, it's kinda nice. And then I can kinda see. Yeah. And eventually, I I kinda have taken a step back into the more simplistic view of things. But I I still do understand the value of a flow like this for keeping things organized.
Scott Tolinski
I think the most important thing with something like this is that it is a highly organized system, and I think that can help a lot of developers maintain their applications.
Wes Bos
Yeah. It's there's a lot of boilerplate.
Wes Bos
Like, if you simply want to have a variable of is cart open Yeah. Yes. Totally. You're you're what you're doing is you're creating a store that has an action of open cart, close cart, toggle cart.
Wes Bos
You'll have a reducer that that will update that variable. Then you'll have a dispatcher, which fires off the open cart action. Mhmm. And then you could also subscribe to it at a different part of your application because if the cart is open, then maybe you wanna do something else in your navigation where the navigation is a bit smaller. It's it's not for simple stuff like that. It's for when your application is extremely complex and having a very rigid system in place, allows for those things not to sorta get out of hand.
Mutation based state is simple but limited
Wes Bos
Because otherwise, if it's super simple, which is our next one, which is mutation based state, which is probably the simplest option out there, which is you simply create some sort of store. And and, like, Svelte has a really good implementation of this. There's there's kind of lots of them out there. You could at the very simplest, you could just make a variable that has a number in it, or you could have an object with a couple properties on it. And when you want to update that state, you simply do it like it was JavaScript.
Wes Bos
You say Wes Scott age equals 57, or you can delete a property or push an item into an array, right, or or filter that array and then overwrite the thing. That's mutation based.
Wes Bos
And the way that that works is it generally either uses a getter getters and setters on an object or on a class that you can use them on both. So in in JavaScript, when you set a property and when you like, we could say Wes. Age equals 50 or Wes you, get a property, which is console.logwest.
Wes Bos
Wes, those are getters and setters.
Wes Bos
And, by default, they're the same thing, but you can overwrite the logic with your own functions as to how does that value actually. And and usually what happens is the actual value itself is internal on that class. It's either a private value on a class or it's like an underscore age value that lives inside of an object.
Wes Bos
And then you also have proxies as well, which is a proxy is sort of a function that sits in front of accessing an object, and you can Scott intercept when somebody runs a getter or setter on that object, and you can determine what actually happens.
Scott Tolinski
Yeah. You could think of a proxy as kind of like a stand in for the actual object, but that's been, like, modified to have extra functionality added on to it. So it's, like, kind of like you said, it's intercepting.
Scott Tolinski
It has potentially, additional functionality, and it represents the object itself.
Scott Tolinski
Proxies are kind of annoying when you have to work with them sometimes.
Scott Tolinski
Like, it's called for instance, their new state is all proxy based. And, like, sometimes you you wanna spread out some state. And with dealing with the proxy, you actually have to take, like, a a clone of that or a snapshot of it before you can actually access the the real object behind the scenes. Yeah. Yeah. So I I'm actually curious about this. You just upgraded the syntax website to Svelte 5. Yes. In Svelte four, a lot of the,
Wes Bos
state was just mutation based. Meaning that you just create a variable, and, you can put the variable somewhere. You can overwrite that variable with a with a new value, and it's it's all reactive, and it just works. So you don't you don't have to know what a getter, setter, or proxy is in most cases because it simply just works, and then the Svelte compiler
Scott Tolinski
under the hood will will take care of all that stuff. Is that still the case in Svelte five? In Svelte five, you do have to understand a little bit more of the proxies, getters, and setters. Because if you wanna have, like, your own custom state function, right, like a create state function that contains multiple state values and is, like, fine grain reactivity, you need to set you need to use getters and setters if you're using a function for that or returning an object. Right? But if you're using a class, you don't have to. So in in Svelte five, it doesn't feel as simple in that regard. But if you are just creating a basic state variable, that's an object or anything like that, you're just creating JS is mutating it, whatever. So it's still mutation based behind the scenes or it's still mutation based in general.
Scott Tolinski
It it it isn't as simple as the writable, readable, way they had it before, but I think it's it's better in a lot of ways. It's a little bit more explicit. There are times where it feels like I'm writing a lot more Node. But I I don't know if if you ever got too much into, like, really custom stores in Svelte 4. We have Node for the the audio player on the syntax site, and the thing's a bit of a beast. And what I'm looking forward to most is converting that to a class and using that as some custom state JS a class in Svelte five, which it's not even though I did the migration, I I didn't touch that code just yet. It's it's still the the old way of doing it. But I I think for
Wes Bos
for big states, it feels a lot nicer. Yeah. And and that's actually a really good example of the difference between reducer based state or, like like, function based state, you know, where you have an explicit function in order to interact with it Mhmm.
Wes Bos
Versus atom based state, which is our our next one. So atom based state is every you can kind of think about it JS if you've used use state in React, kinda similar to that. Whereas every piece of state is is called an atom. And you you break your state into many smaller pieces. Right? So if you have a component that has JS a counter in it, yeah, an atom would be the actual counter.
Wes Bos
And you can in order to interact with that, you don't simply just update it directly, but you have a set of functions to to update it or to access it. Whereas, with use state and react, when you use it, the first item is the actual piece of state, and the second is the actual updater function.
Wes Bos
Atom based state, probably the biggest ones out there are recoil in Jotai.
Wes Bos
Is that how you say it? Yeah. Jotai is fine. And, the the sort of difference between atom based and reducer based is that, atom based is more used for for global Scott. If you wanna have things that are sort of application wide, and there's there's generally no way to define how it is updated. It simply is just your data and a function to update that state.
Wes Bos
Whereas with reducer based state, you often want to define your data as well as a list of functions in in the way how you can interact with it. Right? So if you have a list of of comments, you may only say you may add a comment that has, these values in it. You may update a comment, and you may remove a comment. Whereas with an atom based state, you might just have an array of comments, and you can do whatever you you can do whatever you want with that. There's no way for you to really define how that is is yeah. Of course, you can make a function separately, but that's not part of the state management. That's just part of your application.
Atom based state manages global state well
Wes Bos
Yeah.
Wes Bos
Cool. Oh, sorry. One more thing is the benefit I forgot to say is that one of the big benefits of using this atom based state has to do with some of the annoying parts around rendering in React, which is, I'll just read it straight from the Jotai website. They say build state by combining atoms, and renders are automatically optimized based on atom dependency.
Wes Bos
So this solves the extra rerender issue of React context, eliminates the need for memoization, and provides similar developer experience to signals while maintaining declarative programming Node. So one of the annoying parts about React is that if you want to have some data available to you in a component, If you pass the if you have passed a fairly large state thing, especially if it's global state, if you pass that into a component because you need that piece, anytime any of that state is updated, the whole component re renders.
Wes Bos
So the idea with a, atom based state is that you create these little pieces, and you simply just pass in what you need or you you pull out what you need from the the store itself, and then it will be smart enough to only rerender when that thing is needed. I always find that to be really annoying because, like, Svelte does this, just figure out what I'm using, and then don't rerender when I'm not using it. How about that? You know? And, obviously, it's a lot more complex than that. But, yeah.
Scott Tolinski
I know. I know. I think that a lot of these these state problems have come up from, like, ways to solve problems that were created by problems that were created by problems. You know? And it's like Yeah. Next thing you know, you just have Node thing to exist to solve a problem that something else created. And I don't know. I'm not smart enough to know if this felt way is scalable in the same way that the React way is. But one thing I really like about it is just, hey. You're not thinking about how many times is this thing rerunning or rerendering. You're thinking about, is this value changed? Did this value change? If it changed, then update otherwise or update derived state or anything like that.
Scott Tolinski
So to me, that makes more sense. But, you know, what do I know? Next one is ways to hold state.
Scott Tolinski
So you can hold state in all kinds of ways. We we just talked about a little bit in the mutation Bos where you can hold just state in a straight up object. A lot of times, this could be like a function that creates an object too. You have a function that creates an object. That object holds state. You can use getter and setter methods to set and get values from this. You can use functions or or methods. Sorry. You can use methods inside of there to perform actions and modify the state as well, instead of just getting in and setting it. And that's pretty common. Right? Instead of always doing get and set, you would have a dot increment method that would take the state value and increment it inside of that object. Mhmm. Same thing with classes. Right? With classes, you have, these methods inside of classes. And, again, they're they're modifying this internal state within classes. It is funny how in JavaScript, we tend to use objects for things that most other languages would just go straight to classes for just because classes are really newer and a syntactical sugar around objects anyways.
Scott Tolinski
But, you know, because of because of that, I I kinda stayed away from classes for too long. And I, man, I I tweeted out the other day of just how Svelte five has been making me write a lot more classes lately. Not that it's making me. It's just the syntax ends up being a lot more concise without having to write getters and setters. And, gosh,
Wes Bos
I kinda like writing classes. I don't know what's happened to me. Yeah. I I've always been a big fan of using classes for when everything needs to be self contained.
Wes Bos
And almost always is when I'm writing something in vanilla Wes, like, for example, you are in a lot of my courses, we'll do something where, like, we create a game. Right? And and that game will have internal state of what is the score, who are the players, and then we also have a whole bunch of methods to interact with that. Right? You can increment the score. You can, add players to it. You can pause the actual game. That's that's another one I do do as well, which is a possible set interval. Mhmm. You know? You wanna be able to run a function every 500 seconds, but you wanna be able to also pause it and stop after a certain amount of time. That's a if you want a little JavaScript exercise, that's a great one to do JS a possible set interval that will stop itself after a certain amount of time, and then you can expose all of the ways to interact with that via the the class methods.
Wes Bos
You know what the best state management
Scott Tolinski
library out there is? I do, and I agree with this one. So you can go ahead and URL.
Wes Bos
I hear. The the browser's URL is the OG state management library because if you are filtering something, if you need to make something sortable, shareable, whatever, simply just put it in the URL and have your application UI react based on that. If you take if you go to Syntax Scott FM and you go to shows and you filter for different types of shows, for how many shows you want, for sorting, and what page you are on, all of those things are not buttons or whatever to be able to to do some sort of complex filtering. They're links.
Wes Bos
Yeah. They're links, and we programmatically generate the links to those pages. But the state management for the show filtering is simply links, and you can control how you sort it, how many per page, what type of episode, all of that good stuff simply by visiting different URLs. And because now we have push state Wes you don't actually have to refresh the page Wes you do this type of thing, it makes a really nice state management library.
Scott Tolinski
Yeah. The best part about it JS, for me, is that they're shareable. Right? And if you think about it, if you take a very, like, wide stands out your website or application, even just with a a general URL or general path in your application, you could really think about that as being state. Right? When your website loads or or even, like, when your server gets that URL, it takes that and knows what page to load because that's the state of your website at that point. So it is definitely the URL and query params are really super underutilized, for this type of thing.
Scott Tolinski
Next one I have here is IndexedDB local storage or cookies. There's also a session storage, which I don't know about you, but I almost find myself never using session storage. I don't know why. Maybe that's a a gap in my knowledge. You know what? The use the difference between session storage and local storage is is if you have multiple tabs open at once,
Wes Bos
does is that shared across the tabs, or is it unique for that? Because there could be a situation where you are making you're working on 2 things. Right? Yeah. And you wanna save that, then that might be session storage. And, also, session storage will clear itself
Scott Tolinski
When you close the tab. Yeah. When you close the tab, which you may or may not want. I know. I just don't I you know, maybe I think that doing the same thing in general for you. I rarely use it if ever. But I I think these often get overlooked as a place to store state even though people do often store state inside of cookies. You could think of, like I mean, you're accepting a cookie banner and you're saving that information to say, yes. I accept that we're tracking or not tracking cookies.
Scott Tolinski
That, you know, that save of that state is being saved into to cookies most likely.
Scott Tolinski
And, likewise, IndexedDB.
Scott Tolinski
And that's a whole database there you can save stuff in. Same with local storage and you can pull that stuff up later.
Scott Tolinski
We use that to store like the current like, if you're listening to a syntax episode on syntax.fm and at any given ESLint, that timeline is updating and saving the state of that player into IndexedDB.
Scott Tolinski
And then when we want to load the site the next time, we want to start you off in the exact same place you left off. So we're saving that. We're capturing the state of that and keeping the state of the player in IndexedDB and using that to to control the interface when the page is loaded.
Wes Bos
Maybe Node one thing we haven't talked about here, but it's it's probably worth mentioning that you're talking about IndexedDB is like like sync engines. Right? The whole local first, being able to communicate with the server and and possibly even the database Dude. Is is often being attached
Scott Tolinski
to your state management. Right? Yeah. Let me even tell you. I've been using a platform 0, which I'm really excited about from the Replicash folks. I'm not gonna go deep on this until they fully release it, which I'm sure they they will somewhat soon or at least they'll release an alpha version of it. But when you work with something like that, where the cache the front end cache of your site is one to 1 with your database, and I'll save locally, you really do start to have your database be the state of your application.
Scott Tolinski
It it's pretty dope.
Wes Bos
That's wild.
Wes Bos
Form data is is a way to hold state. I thought this was I I was like, is that a state management library? And it it kind of is. So form data is in API and JavaScript to hold data, because forms forms can be complex. Right? You might have multiple inputs. You might have multiple inputs with the same name. Right? Like, for example, if you have a pizza order form, you'll have toppings, and you'll you'll have multiple toppings that need to be stored. So you form form data is a great way to store data, especially because that API is standard. It's standard in the browser. It's standard on the server. We're seeing a lot of, remix, React server components. I'm like, what are the hard things? Form data, Svelte. Pretty much all of these libraries that expect data to be sent to it is being sent via FormData. So and, also, FormData has a really nice API. It has It's a nice ish. Getter and setter methods.
Scott Tolinski
It has sorry. You said what? I said it's a nice issue API. I would wish I could just do form data dot property.
Wes Bos
That would save me a lot of grief. Yes. Scott get. Because, yeah, you you have to use Scott get and dot set and dot has. And if you wanna be able to loop over what is in your form data, it can be a little bit complex.
Wes Bos
But there's there's methods for that, but it's it's pretty sweet. You can check. It does it has a dot has method.
Wes Bos
So if you wanna check if your your value is in there, it's pretty nifty. So form data, kind of a way to hold Scott. Great way to set at least to send your state from your client to your server.
Scott Tolinski
Yeah. For sure.
Scott Tolinski
The next one we have here is signals. Now it's so funny. We've done so many episodes talking about signals. But whenever I I see, like, signals in this kind of context, I'm just always thinking like, what exactly makes them special? Do you know what I mean? Like, what exactly makes them interesting compared to, you know, some of these things? But a signal really is it's a way of
Wes Bos
it's like an observable state. Right? Signals are a great way to define reactive state. Meaning that, instead of in JavaScript, if you think about it, like, not even in terms of reactor or any frameworks out there, if you think about I have this piece of data that other people may care about when this data is is updated. I may care in other parts of my application where when this data is updated, you may want to store that data in a signal so that in other parts of your application, you can subscribe to that data. You can have an effect when that data has has been updated. I always recommend to people, if you wanna really understand signals, there's kind of 2 ways to do it. 1st, go to the Solid JS docs and just read through their signals documentation in, like, 10 minutes or whatever. It's probably one of the best implementations of signals.
Wes Bos
The other one is Preact JS has this has a signals library, which is not tied to React. So people always say, oh, I'm not using React. It's it you can use it with vanilla JavaScript. So try to build a little application where Wes you update the data in vanilla JavaScript, anywhere that state is then used will will be updated. And the React Wes library, it's like, I don't know, it's like 200 lines of code or something like that, and it's a really simple implementation that really helped me understand it. And then, of course, we have sorry. Go ahead. Oh, no. I was gonna say yeah. And also another great place to learn about this is
Scott Tolinski
the signals proposal because they're proposing to add signals to JavaScript as a whole. Now it's only stage 1. But the explanation JS really good, and it makes a great use case on why. And even shows, like, computed properties, which we we mentioned a little bit. But let's say you have a value that's derived from another value.
Scott Tolinski
This is a a a good way to use signals because, again, it's if 1 value is changing, then we're able to modify another value based on that values change. Right? You're having a computed property. And I know derived and computed properties are built in and baked into Svelte and Vue.
Scott Tolinski
And honestly, there this JS a really great way to work. Because I feel like a lot of times we end up having derived state without even thinking about it.
Wes Bos
Oh, yeah. Absolutely. In in the React world, you you generally just like putting that into your templates or you have a function that will will derive it for you. Then you have to worry about memoizing and Yeah. Or if you wanna listen for when that derived value is of a specific value, then you're getting into having to to code, like, a custom use effect. So I'm I'm pretty excited about this,
Scott Tolinski
signals proposal, and I really hope that it makes it in. Me too. Yeah. Especially because it's how I've gotten used to working. So if that becomes baked in and since it's it's a lot of how you work in Svelte, I I think, you know, their their plan is with their new state. I think they designed it around once this does get into the language, which I think inevitably it will, that they could just, you know, remove a lot of their library code from that. Another one that we don't often talk about, we did mention a little bit when we were mentioning local first, is the server database can often store state. I think about, like, user preferences are often like application state. Right? Whether that's a user theme, the whatever user preferences you have, those are more often saved in the actual database because you want those to persist from device to device or you want them to persist, more so than just an individual client.
Wes Bos
Yeah. And we talked about the the sync engines.
Wes Bos
For example, in my course platform, we have some Scott, which is where are you in the current video. Right? You wanna be able to to do it. And then we also have state as how have you a list of all the videos and which ones have you watched and how far along each of the videos are you. And and that allows us to render out a list of videos and and check off the ones you've watched and and and show you a little progress bar on the ones that you're half done.
Wes Bos
And that's that's interesting because that state must live client side because it has to render out the list of videos and where you are and update every every video update, which is every 5, 10 seconds. But then it also has to be saved server side because if you you come back the next day, you you want all that data to be done. Right? And that's where you get into needing a a sync engine or just a just a function that pings that data to your back end and and actually saves it. Word.
Wes Bos
Global versus component Scott. The we kinda covered this, but the idea of global state is that something that needs to be accessed anywhere inside of your application. And then a component or local state is state that generally just exists inside of that component. So if you have a contact form, you might just have local state inside of that contact form to Sanity the inputs, manage any errors that need to be displayed, any anything else like that. Right? Whereas a a global state may be something about who is the the current user that is viewing this type of thing. Right? You need information about the user everywhere, or is is the cart currently open, or what video is the current user is watching. You may need that data globally. And if that's the case, you stick it globally.
Scott Tolinski
Yeah. I know. An example I had on this is my my habit tracker.
Scott Tolinski
What what month you're on because it shows a month by month view. Right? Several parts of the application need to know what month you're on at any given ESLint, whether it is the the list of habits or any sort of form you have, things that are not connected in the tree. This is, like, important state for the entire application to know. We're like, yeah, you have a a Node or a drawer. That thing is local state. It's either open or it's closed. Right? And and global state doesn't have to be, like,
Wes Bos
application wide. It it can be something that lives just at a certain level because, like, for example, if you wanted to show multiple, months at once, then you would have 2 of those components, each with their own state.
Wes Bos
Right? Branch state. Local to some component. Yeah. Branch state. That's a a good way to put it. Yeah. Totally.
Wes Bos
Sharing state. How do you share state? There's kinda 2 ways you can do it. You can import and export the state into the components that you need. This is generally my preferred way to do it where you have, like, a store dot ts file. You create the store in there along with any other functions as to how to update it. And then any anywhere you need that in your application, you will then import it. That's that's good for global state. The other way to do it is you inject it at the level that you need it, and then you can pass it down somehow either via context in React JS is a common way to do it,
Scott Tolinski
or you simply use prop drilling, which is you pass it down via props 2, 3 levels. Any anywhere past 2 or 3 levels, it starts to get a bit hairy. Yeah. And and this actually is something interesting if you're working with server side state. You kinda always have to be careful. Like, if we have server side global state and it's being defined and created outside of the context of the current, like, loading flow, that state could be created accidentally globally server side. So you do kinda have to pay attention to JS this state being created for this specific user in their specific path? Or is the state being created globally, and all of a sudden we're shoving, sensitive information into this this global store by accident that perhaps is available to the entire
Wes Bos
server. Right? Yeah. And that that simply can be a variable that is scoped to your module. So you're a handler where someone visits a page on their website.
Wes Bos
Inside of that handler, you're you're gonna have local variables. Right? But if you touch a variable that is above that handler but still inside of the module, those are shared amongst, at least in JavaScript. It's not the same in in other languages like PHP, but, those variables are shared, and and you you might want that. That's that's great for sharing data between Wes. For example, on the syntax screenshot tool that we use for, the Open Graph images, we stick a global variable for the browser that takes the screenshot so that it's faster every single time that you use it. But if it's sensitive state, you don't wanna do that. Right? Totally. Right. Yeah. Absolutely.
Scott Tolinski
Let's talk about state library specifically. We've talked about a lot of these over the course of this episode. But if you're wondering about state libraries, it it is funny that the way that this kind of works is that you have a whole ton of state libraries for React.
Scott Tolinski
And then you have Solid has their own signals based implementation.
Scott Tolinski
Vue has their own state in in, like, kind of built in state with Deno. And then you have Svelte which has its own state implementation.
Scott Tolinski
So when we're talking about state libraries, it almost has to be like these are the state libraries for React because, I don't know why. But it feels like React JS just one of the ones where they they they have the local state figured out, but maybe, like, more advanced state. They're just, like, alright. We'll leave it to user land. I I mean, I don't know. Like, do you do you feel like you need a library? But even before we get into the libraries and stuff, in React, do you feel like you need a library beyond context and state?
Wes Bos
I I do because because of the the rerendering issues in in React. Right? Like, ideally, you use state for whatever you want. You stick it in a global context, and then you can grab it out of context whenever it is that you need it.
Wes Bos
But there's there's performance issues that sort of come along with that. And, like, I'm not don't know. I don't absolutely love the API for that type of thing. I'd rather just import it wherever I want, and you can kinda get that that API with with a custom user or a custom hook. But Yeah. I, I prefer the other options that are out there when I'm doing a little bit more complex stuff. So I'll I'll give you an example. So I just rewrote my checkout for my my courses, and I was like, I need something to hold all of the state for the checkout. Right? Because there's going to be, all the information that the user has typed into the boxes. There's going to be information about what course they're trying to buy. There's coupon code information.
Wes Bos
There's error and success messages that need to be displayed, all kinds of stuff that goes along with with that. And I thought and to make it even, harder on myself, I wrote the checkout in React, but the actual website itself is just vanilla JavaScript.
Wes Bos
And I needed to be able to share the state between vanilla JavaScript and in the React world.
Wes Bos
So, I actually opted to go with Zoos stand Cool. After looking at all of them. And it's a pretty nifty Node. First of all, because it works in vanilla JavaScript, which is something that a lot of times people need. Right? You might not be using a framework. You might just be writing some vanilla JavaScript because it's it's totally doable, but you still need the ability to listen for changes and to be a little bit more complex with how things work. So ZoosDend was was my choice there. And the way that ZoosDend works is that you create a store with your data in it, and then you also define the updater functions that go along with it. So if you their their example is you have a store called a bear store, and you have how many bears you have. You have 0, And then you can also define increased population and remove all bear functions, which will increment or reset the number of bears in that store.
Wes Bos
I don't absolutely love the API because it makes you when you want to use one of those functions or you wanna use a value from your store, I'm used to just like bear store dot bears. You know? I just wanna reference it. But because of the way that rendering in React works, they say it's better to use this, like, weird callback function API Mhmm. Where you simply just pick and choose the parts you want for that component. And the benefit to that is that you explicitly are telling it what you're using. But this comes back to my whole, can't you just figure that out for me? I know. Maybe with a compiler. Using the variables.
Scott Tolinski
Yeah. I know. I I like Zustan the most, in the React ecosystem.
Scott Tolinski
I I have it's funny. I I spent so much time in the React ecosystem that I used Zusdand in production code. I've used Redux in production code.
Scott Tolinski
I I never really got into MobX.
Scott Tolinski
And MobX is kind of an an interesting state because people like MobX. And and what's interesting about MobX is that there's also MobX Scott tree. And, like, just like with Redux, when you're talking about Redux a lot of time, people have their own Redux stack of all these different Redux thunk Yeah. Whatever stuff. And I honestly, the amount of things there, whether it's using just MobX or you have to use MobX Stateray, whatever, That conversation has turned me off so much from using that I never used it. Even though I'm quite sure that I would like MobX based on what I've heard about it. Yeah. But, again, it it feels too complex to me in that sort of way, and I'm sure it's just a skill issue or something I haven't really you know, it's not anything I've I've done before. But yeah. I don't I don't know. I don't have too many thoughts about MobX other than I know people like it, and I know people use MobX Scott Tree a lot.
Scott Tolinski
Have you done any MobX work?
Wes Bos
I have not, and I think it's just due to not necessarily needing, that types of thing. Right? The the types of application that people are building when they use MobX or Redux or x date x date store, These libraries require require a lot more boilerplate, and I also just feel exhausted looking at the documentation for these type of things because, like, the simply setting up a variable that needs to be updated.
Wes Bos
Wow. That it requires its own file and and, like, 40 lines of Node. But I understand that that's not everybody's use case. People want to have full control over how this data is is updated and how it's stored and how you can subscribe to it and all of that good stuff. So I certainly understand it, especially as you get into more complex applications.
Wes Bos
Like, for example, their their most, highest sponsor for MobX is Canva.
Wes Bos
Right? Oh, you're building entire Photoshop in the browser? Yeah. You probably are gonna be thinking a lot about state management.
Scott Tolinski
Yeah. I know. I do feel like man, I feel like isn't MobX? MobX is is is signals, is it Node, or it's observables? It's observable based. Yeah. It's observable based. So and and just looking at the the docs for observe or for MobX in general, it looks like a slightly more complex version of what I'm using in Svelte. So for me, I'm sure I would like it if I got past that initial feeling of, woof, because I I felt that way about Redux. And when I started using Redux again, like, I definitely got it more. I I don't think I ever, like, truly was, like, yeah, Redux the best.
Scott Tolinski
But I I do understand the utility of it. And so maybe that's just I bet it's just a, a blindness, a a skill issue. If you're using MobX MobX State Tree and you wanna kinda give us a what the heck's the difference there? What do you actually use? What are people actually using in MobX land? I wanna hear about it.
Wes Bos
There's also Jotai. Am I saying right? Jotai?
Scott Tolinski
Jotai. Yeah. Jotai.
Scott Tolinski
Yeah. Two syllables. Jotai.
Wes Bos
So I explained earlier that Jotai is more of a, like, a primitive. And if you want, just, like, quickly get up and running.
Wes Bos
Not to say that it can't be used for complex stuff, but if you want especially for global state, Jotai is really good. It's similar to how, React does use state, and you can combine them together. It's a really nice API, and often used for you can use Jotai and Zustan together. I believe they're by the same developer. Is that true?
Scott Tolinski
It's possible. I felt like they were at some point, but I I guess I don't know now that you say that.
Wes Bos
Yeah. Hold on. Let me let me look this up. Zustan and Jyotai are written by the same guy. And, oh, even Valteo? This is another one I've not checked out as well. Proxy state management for vanilla and React.
Wes Bos
Man and the same guy is working on, like, Waku, which is a rec server component framework.
Wes Bos
So, certainly, those are all worth worth checking out. And it's it's very clear that if the same guy has built 3 state management libraries that are very good, it's clear that there's different ways to approach and solve these problems.
Scott Tolinski
Now if you're listening to this episode, you know the answer to that.
Scott Tolinski
There's also XState, which we talked a lot about state machines. And XState is a really cool, platform because it basically allows you to have a system of working within state machines specifically.
Scott Tolinski
And it feels like something, again, that if you're building complex applications, Xstate feels like it would be a really great option to go with, especially if you're having a hard time wrangling, like, the actual state of things. And there's a great little visualizer that, they have on the the site and helps you build state with a visualizer.
Scott Tolinski
I do like all of that.
Scott Tolinski
What is this XState store you you have posted here? Yeah. So XState store is from
Wes Bos
David k Piano, and it's sort of a simpler version of XState. I I don't know if this is true, but I think a lot of people say that's XState is cool, but I I don't necessarily have those problems.
Wes Bos
I've said that many time. Right? So x date store is sort of a simpler version of that Wes you can get up and running. It's it's very similar to the, reducer pattern that we just said, which is you you create your store, you create your actual initial data in it, and then you can define the the function updater functions that, how you can interact with that actual data. I tried it out when I was evaluating it for my cart checkout.
Wes Bos
Yeah. But, again, it just felt there was there's 2 things. First, it felt like a little bit too much boilerplate code for me. It Scott was not needed.
Wes Bos
And then the other Node Wes, I didn't like that Wes when you want to run a function.
Wes Bos
Like, for example they have an example where they have a doughnut store, and they have 0 doughnuts.
Wes Bos
And then when you wanna add a doughnut, what I would like is donut store Scott add donut function. Yeah. But what it actually is is donut store dot send pass an object with a type, and the type is a string of add donut.
Wes Bos
And, again, I get that because it's it's very, very complex, but I don't like passing my, like, functions as strings.
Wes Bos
And I know that people are probably cringing at me right now, but I just want a nice function that I can run, and Zoosdend gives you that. You're just trying to function. Remember that song?
Scott Tolinski
Or have you ever that I should be saying? I know you should be saying it, but oh my god. What year did they come out? 2020, 2019? Maybe even older than that. Man, this is gonna be really embarrassing if it's, like, 2015.
Scott Tolinski
Hold on. I'm just trying to function.
Scott Tolinski
Oh, no.
Scott Tolinski
Oh my god. Wes, this this song came out 12 years ago. Oh my gosh. On 2012.
Scott Tolinski
And I was thinking 2012 in my mind will always be 8 years ago Node matter how fast the the things go. 2012 was 8 years ago. And you know what? I should have known it was this long ago because they they made a joke about it on Workaholics, and that show was at its peak in 2012, probably.
Scott Tolinski
So
Wes Bos
Other state management libraries, there's another one I found called Easy Peasy, which is similar to Redux, but kind of a kind of a nifty nifty little, API for working with it.
Wes Bos
And it looks like it's in under very active development, a vegetarian state, friendly state management for React. So this one looks pretty cool. And as a whole, like, React hooks API with it.
Scott Tolinski
N I a, which I thought it was Oh, yeah.
Scott Tolinski
You're right. Wow. This is a yeah. This is definitely a moment for me. I thought it was the same way that you were saying it was. But I I do think a lot of people just use the built in view state. But if you need, like Yeah. Bigger state, more modular, say, if this is, like, the community
Wes Bos
approved one, so to say, this is what people are using. If you're doing a lot of, like, fetching between APIs back and forth, doing mutations, being able to update data, 10 stack query is is 1. Yeah. Yeah. It's like, I I would consider that state management as well as, like, a whole HTTP library because what it does is you can give it, like, a promise, which is post to a, endpoint to update some data or use a get request to to load in data. And then you also get variables like loading variables, and you get to you can control how the data comes back. You can cache it. You can refetch it. So 10 stack queries is kind of an interesting one because it's a state management library plus a whole bunch of stuff for working, working with the server.
Scott Tolinski
Alright. Well, that is it. That's a lot of stuff. Yes. That is state in JavaScript. I know a lot of these things are React Scott and React, but this is state JavaScript in general. And a lot of these libraries that we did mention can be used, with Vanilla as well. Let's get into the part of the show where we talk about sick picks.
Scott Tolinski
I have a sick pick for you today, and it was 1 because we just did our our holiday sick pick episode.
Scott Tolinski
It's one that I actually had in that, but we hadn't I didn't have it as a normal sick pick. So we'll do it again just in case that episode didn't appeal to you.
Scott Tolinski
And I don't know about you, Wes, but I've been looking for men's body wash for a long time that is like not been looking for that. No. Yeah. I don't I don't know why. But, like, I never found a lot of men's body wash that I I really liked. I know a lot of it's just cheap garbage or whatever or just smells like normal. But I wanted something a little bit more, like, manly smelling. So I I found this brand, this Cremo Cremo, and they all are, like, branded after different types of, like, whiskey, whatever. And for the most part, you don't have to worry. It's not like it smells like whiskey. But I I found this stuff to be really nice. Just about every one that I I've smelled so far has a bit stronger of a smell, but it it is nice kind of, like, deep and smoky type of of smell in general or those types of things rather than, like, I don't know, just lavender and eucalyptus. So, I yeah. I've been a fan of this. I think somebody recommended it on Reddit. And, since then, I've I've tried a few different ones, and they they make shampoos and conditioners and stuff as well.
Scott Tolinski
So if you're out there and you're looking for a little bit more of, like, a manly Node smell, this is this is pretty good.
Wes Bos
I I'm a big fan of the, Suavecito.
Wes Bos
They have a body wash, but they also just have, like, a bar Bos soap that smells amazing. And it's a huge bar of soap, and lasts forever. So I've been I've been using that for a couple Yarn now.
Wes Bos
Big fan of that. And, my kids my I don't my kids don't love the smell. You know, like, when you're a kid and, like, you would smell some, like, old dude with, like, musky cologne? Mhmm. I wonder if it's similar to that. I love the suavecy dough scent that they have, but, my kids don't love it.
Wes Bos
I'm gonna sick pick a bento box that we got for our kids. So we switched from sending our kids to school with lunch pails to just sending them with a single bento box because what was happening is they would come home and, like, the the school doesn't want you to use, like, any plastic bags or anything to give them their snacks in. So we've we were having, like, a thousand a whole dishwasher full of these little cups that you had to wash, and it was getting to be a bit much. So we're like, what if we did move to Bento boxes? And Yeah. We tried a couple of them out, but they're all way too small, to actually like like, what are these kids eating? Like, 1 cucumber and, like, half a sandwich? Like, none of them actually fit a full sandwich in there. So we finally found it's called an adult bento box, which is silly because they are fantastic. It's 3 levels, and they have rubber seals on them so you can you can send them with wet stuff or Jell O. They're they're microwavable so they can pop the bottom off, throw it in the microwave at school.
Wes Bos
And I searched for probably a year. My wife is like, we need bento boxes, and I would be like, these all are awful. They're all way too small. And we finally found one that we're we're a big fan of, so I'll link it up. It's it's called the JS Cares Bento Bos with the 3 levels on it. Wow. Okay. I'm gonna actually even,
Scott Tolinski
follow this up because Courtney has a 3 level Bento box that she uses for her lunch, which is by Bentgo.
Scott Tolinski
And I think it's really nice because it it has, like, a a thing for salad dressing. It has a spot for a fork to get stuck in there too so you can always have a Oh, yeah. A fork utensil. And I actually really like hers. I don't have one myself because I'm always eating here. We got the the kids bent go ones for the kids, but you're right. They are pretty small like some We looked at them. Them. We went to Costco, and we looked at the the bent bent, yeah, BentGo.
Wes Bos
And there's the dividers are, like, half the size of they're way too thick, and then they got some of them have, like like, water in them so you can freeze them, and it maintains cold. And, like, that's too heavy for the kids' backpacks.
Scott Tolinski
Yeah. I I I does I do feel like ours are too small for stuff. Because when I'm filling my kids' lunchbox, I'm like, how am I supposed to get all of this stuff in here? That was the problem we had. We because we looked at that. Costco sells those Bentgo ones, and they're they're no good.
Scott Tolinski
Yeah. Well, we use them. They're nice, but they're they're too small for sure. Yeah. I agree with you. Yeah. Definitely check this one out. Yep. Cool. Sick.
Wes Bos
Alright. Shameless plugs. Check out, the Syntax YouTube channel.
Wes Bos
Subscribe.
Wes Bos
Watch.
Wes Bos
CJ just released a video on mapping software,
Scott Tolinski
so alternatives to Google Maps, and really good video. You're gonna wanna check that one out. Yeah. Super good. Cool. Well, this is, as real as always, so we will see you in the next one.