Build a Fullstack Music App with Next.js Player State with Easy Peasy
A second version of this course released using Next 13+, but this course is great if you want to see another example fullstack project. We now recommend you take the Build a Fullstack App with Next.js, v2 course.
Transcript from the "Player State with Easy Peasy" Lesson
>> In order to start working on the controls and everything. So we don't have to backtrack, and come back, and double take, and do all these like refactoring. I wanna get the state situation figured out before we start working on the UI. And the whole situation with the state is I mean because go look at the app, I wanna come in here and I wanna click play.
[00:00:20] So play this entire playlist, or I wanna come in and I want to click a song and I want it to play, but how does this player board know that? Right now, we don't have any state situation set up to where we can understand what is actively playing, what is the active playlist?
[00:00:34] That's not something that we have set up, we've just been using local state and hooks for now. So we need to set up some type of global state that we need to use so that these two components can communicate with each other. And there's a million ways to do that.
[00:00:46] You can can use Redux, that's what Redux was created for. In the world of hooks, you can use hooks plus context API. There's performance trade off to that, unless you use it correctly. Basically, you have every component re-rendering all the time, which is a very common thing that I see when people will hooks and context.
[00:01:04] But I'm actually just gonna use this super easy drop in state library that works very well with hooks. It's almost like Redux but it's just way more lightweight and not a lot of ceremony and setup. And we'll use that to get our state. And again, we need to keep track of the active playlist, and the active song, and what those are.
[00:01:25] And we need to be able to change that state so that way this component knows about it. So that's what we'll be doing. So in order to do that, you should already have something installed to help us with that. So what we're gonna do is we're gonna go to the lib, we're gonna make a new file, we're gonna call it store.ts.
[00:01:45] And inside the store, we're gonna import something from Easy Peasy [LAUGH] I said it is easy, it's in the name. It's literally called Easy Peasy. I like the fact that the creator's called it this because it is really easy. It won a bunch of awards for how easy it is with React.
[00:02:05] So we're gonna import createStore and then we're gonna import action. So if you ever use Redux, you probably already familiar with those two things. We're making a store, there's action but it's not the same. I think internally it does use Redux, I'm pretty sure Easy Peasy uses Redux internally.
[00:02:19] But it just abstracted away so well that you just don't even know where you don't even care. So we wanna create a store, so we're gonna export cons store. And that's gonna be createStore, and basically the way the store works is you can put some state on it and then you can put some actions on it.
[00:02:40] And you can also put computer properties but we don't need that. So as far as the state, I wanna keep track of the active songs and that's going to be an array. I wanna keep track of active song singular, and that's just gonna start off as null. So those are really only two things I wanna keep track of.
[00:02:56] And then I need actions to change those things, to modify those things. So I'm gonna make an action for changeActiveSongs. And the way you can do that is you just set that to the action import that we have, which is a function, that just takes a callback. So it'll take the state and then it'll take the payload.
[00:03:17] And then you can do a mutable operation here. So I could say state.activesongs = whatever the payload is. So that means when you call this function, you have to send up the new active songs. And right now, it's freaking out because a TypeScript so I'm just going to need that thing.
[00:03:38] Underneath that is using something called Immer. Which I think a lot of people use Redux now, and Immer what it does is it allows you to do mutable operations like this using an equal sign, but underneath that, it'll transform it to immutable operation. That way, you get the best of both worlds.
[00:03:56] You don't have to do all, if you've ever had to write a reducer or Redux you know what I'm talking about, what spread operators and it gets crazy when you're trying to be immutable. And no one wants to use the immutable libraries cuz that's just not the way that we write code.
[00:04:11] No one wants to do get and set everywhere to change an object. So Immer allows you to just write code like it normally is and then underneath it transforms it to an immutable operation for you. So I'm pretty sure that's what Easy Peasy is using, I think even says it in our docs.
[00:04:28] And then the next one is just another action to change the act of song, so changeActiveSong, singular. And it's pretty much the same thing. I was actually just gonna copy this cuz it really is, except for changing state.activesong in our active songs And that's it, that's our store and we're done.
[00:04:49] [LAUGH] It's really easy. And then using it is also very easy, it works with hooks, so we'll be good to go there. The last thing we gotta do before we start using it in the hooks is that we just need to, in order for everything to have access to this store in the state, obviously, I think context is going to be applied here, just like any other thing would have context.
[00:05:14] So we're gonna have to wrap our app in a provider which has gonna have access to the store. So what we'll do as we'll go to the _app, we need to go up top and we have to import, From Easy Peasy, and that's gonna be the store provider store provider.
[00:05:33] There we go, and we just need to wrap the whole thing in a store. So pretty much everything after ChakraProvider is just gonna get wrapped at the StoreProvider. So we'll say StoreProvider, that's and all the way down here to the StoreProvider. And then as its only prop, it's gonna take the store that we just created, so it will say store and then store that we can import.
[00:06:03] And the next thing we wanna do is we want to pull in our state into the components that are gonna use them. So the only component that's gonna use the state is gonna be, probably the actual controls for the player. So that component that we haven't made yet, so what we'll do is we'll make the component for that.
[00:06:24] And then we'll just pull in the state and we'll start building out the UI for that. And this components gonna be a little bigger than most of the other components because, like I said, there's a lot of things to keep track of. There are a lot of DOM events that were responding to.
[00:06:37] There's animations, there's the state thing now, so it's gonna get pretty crazy but that's the fun part.