Lesson Description

The "Nanostores" Lesson is part of the full, Enterprise UI Development: Microfrontends, Testing, & Code Quality course featured in this preview video. Here's what you'd learn in this lesson:

Steve dives into Nanostores, explaining their state-management concept of an "atom," a simple value container that can be read, set, and subscribed to for changes. This approach works across different frameworks like React, Svelte, and Angular, helping solve communication and state-sharing problems in complex applications.

Preview

Transcript from the "Nanostores" Lesson

[00:00:00]
>> Steve Kinney: So the kind of primitive in nanostores is this idea of an atom. There are other state management libraries that use the same concept. Jotai is one of them, J-O-T-A-I, very similar. It's like a React state management library. I think you can probably use it anywhere as well. Very, very similar to this one as we go along too. And effectively under the hood, it's like a proxy event listener game, you know, that you can play with as well.

[00:00:32]
And so you can kind of take, you can hand it like effectively any kind of value. So we're going to make a new atom, this case is going to be zero. You call doc.get on it. It's zero, you call .set. You set it to one. You call doc.get. It's now one. Great, cool, neat. Obviously the important part is this piece right here, which is then you can also subscribe to value changes. So this is where it all, this is where the framework interaction happens, right, which is now you have this thing that you can change the value of, like, are they logged in or not?

[00:01:13]
And then you can also listen to changes to that value in all the other context APIs of all the modules, right? And then listen to that like, oh, the auth state changed, wrap it in a hook. Move on with your life, right? And so like, again, a little bit of complexity of all the different pieces of complexity we've seen, not the worst. Also the fact that like you could see a world where you might just use this for your normal state management in a lot of cases, because you can just now pass these to components.

[00:01:44]
It's not necessarily prop drilling, it's just a JavaScript object again. I have written this myself, not because I'm a hero. I just didn't know it existed at the time. Like I wrote it myself because I thought I needed to, and like there's parallels to this in other frameworks. And like that will solve most of it, like it will return an unsubscribe function, which feels really nice if you use React and use like useEffect, right?

[00:02:13]
Because like, useEffect is supposed to return a function that then like unsubscribes. So really you could just effectively have a useState and a useEffect and a useStore hook, which they provide to you as well. But again, it is like 10 lines of code you could write yourself probably too. And now you have this object that if the auth state changes, like that goes in the kind of shared piece across the different module federation pieces and then like that will actually solve some of your communication problems.

[00:02:41]
Solving the communication complexity across all of these, none of it is particularly hard. It is take one of these values that is agnostic to the framework that like announces it updates through some kind of subscribe mechanism. Use that, you're good to go, but it is a thing that you need to do. And, you know, kind of we were talking about before, if you're the one team with four micro repos, you can do it.

[00:03:09]
Obviously, if you are one of 60 teams, there's, you know, some amount of like agreement that has to get reached, right? And, you know, some of the problems that we're going to talk about of complexity are not actually technical problems, they are people problems. And there's some other niceties here too. Yeah, none of this is particularly, that is particularly hard. And so like, you know, JavaScript objects are passed by reference, not by like the value, right?

[00:03:40]
So like a one is different than a two in JavaScript, we know that. But like if you have an array and you push another value onto it, right, it's the same array in memory. If you change the value of an object, none of that would be a different object to React ever. And so this is giving you a bunch of niceties. So you can say like, okay, we saw it with the number zero, changing it to one. Here we've got an object, right, with some keys and values, and then you can just basically do set key theme from dark to light.

[00:04:12]
Woo, everything changes to dark mode all of a sudden. You know, nothing particularly. If you have nested objects, deepMap is a little bit more of a programmatically intensive one because it will like go deeply through the object, and now you could change a deeper value. I will always, and you can, you get nice, you get some niceties again. Could you write this all yourself? You could, then you have to do the work of making it type safe.

[00:04:34]
I mean, or you just let Claude run at it. I don't care. But it's a library, it exists, and you get a bunch of niceties here where you can set a key, you can get the key, so on and so forth. You've got the idea of we can get computed properties. If you've ever used any state management library, this should look like almost all of them to you, right? But it's nice, it's there, and I will show you really the more important part that I wanted to get to.

[00:05:02]
Oh, there's, I wrote up how it works under the hood, look at me. If one wanted to write their own, obviously that does not have all of the like deepMap map stuff, but like if you're like, what is the secret sauce behind this, this is my super naive version that I called it atom, I called it something, I think I called it a store and like I just grabbed it from some other codebase. It keeps track of a bunch of event listeners.

[00:05:27]
It tells the event listeners when the value changes. You could probably use getters and setters and probably even like a proxy if you really like wanted to, except that every time I try to use proxies with TypeScript, I end up regretting it somehow. I'm always like I'm the smartest JavaScript engineer ever. When I first started, I'm like this is going to be the best thing I've ever done ever, and then like TypeScript always ends up hating me at the end, so I don't, but yeah, if one wanted to write their own, this is effectively how you do it.

[00:05:58]
So then there's also like useStore, which again, I could probably like live code one if this was a React course on how we would do it. There's a setState with the initial value. There's a useEffect that's subscribing to it. It's setting the state when the value changes. It's unsubscribing. It's like 10 lines of React, but the nice part again is not only is there @nanostores/react, there's @nanostores/vue.

[00:06:24]
We were joking, I think, during one of the breaks that almost all of the like frameworks are not that much different anymore. Case in point, there's, you don't even need to use a library for Svelte because Svelte has a rule which is anything that has a subscribe method and follows a certain contract, you just put a dollar sign in front of it and it counts as a store, and so Svelte, you don't even need a library technically, you can just use this thing, but in Svelte you already had stores to begin with, so whatever.

[00:06:51]
But the nice part is if you just decide that they're like, we're going to use React and that other thing is going to use Svelte, which, as I think I alluded to before, the use case for that is you're migrating from one to the other, right, and you're doing it, we'll talk about migration patterns later, you know, having a library like this is super useful. You can do it in Angular. I think we get the point at this point.

[00:07:16]
You can use it in vanilla JavaScript if you wanted to. You just pass a function in, and so that's nice if you're doing a refactor. It's nice if you're doing a migration. It's nice if you don't want to write it yourself. If you want to write it yourself as a fun experiment, that's also I think just a great learning opportunity. I would not discourage you from doing it as somebody who's done it a bunch of times, and will probably do it again because I don't learn my lesson ever.

[00:07:42]
It'll work with web components because it works with vanilla JavaScript, and so having one of these values that you can kind of pass in and pass around will solve a lot of those problems for you. The important thing I just wanted to call out is that it's just a problem that you have to solve. I also wrote up a little bit more about broadcast channel and some of the other ways to do this, again, at the fear of getting, of trying to stay a higher level than just React.

[00:08:08]
I have intentionally kind of left those as like exercises to kind of like explore as well, but to know that there are options, one, to be aware that there's a problem to be solved, and two, that the solution is very easy.

Learn Straight from the Experts Who Shape the Modern Web

  • 250+
    In-depth Courses
  • Industry Leading Experts
  • 24
    Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now