Check out a free preview of the full Testing and Modular Front-End course

The "Choo" Lesson is part of the full, Testing and Modular Front-End course featured in this preview video. Here's what you'd learn in this lesson:

James updates a web app to use Choo, a modular redux architecture that uses modules such as yo-yo, hyperx, and sheetify.


Transcript from the "Choo" Lesson

>> So everything that we've done already, including a writing system that works exactly like I've just shown you. You can get all in one way, all in one package with this thing called Choo. So if you do npm install choo like this, then you sort of get set up with basically the architecture that I've just laid out using most of the same modules.

In fact, it uses yo-yo and hyperx and bel. And it's built around this CSS system called sheetify, which you don't have to use. But if you wanna use it, it works pretty well. And this is just a way of managing CSS, yep.
>> If you have the modules within Choo already installed, and then you install Choo, would there be any conflicts or issues?

>> Not if you install Choo. No, there shouldn't be any problem with doing that. Okay, so we can rewrite our code now to use Choo instead of doing everything ourselves. So if I just make sure I have it installed first. Yeah, good, okay. So we're gonna use Choo and that's gonna set up some things like the router for us that this push state and a handful of other things.

But Choo itself is only 4 kilobytes, so it can't really be doing all that much, I figure. Now instead of requiring yo-yo, you can just require a choo/html, which does the same thing. It's using the same libraries even. And now, instead of calling emit on update, we can emit, the event name is called render instead.

That's just a convention that Choo does for you. Okay, so we can create an app, like that. You can mount it onto the DOM, so like this. So we don't have to create that root element anymore. So we can get rid of that code. Cuz we don't have to call our update function right away cuz Choo is gonna handle that now.

So don't have to have an update listener. Gonna take our update code and move it up a little bit so that we can put it on a route. So what that looks like is you call app.route. You give it a path where you want this to be defined.

And then you provide a function. And your function can return this DOM tree. So with hyperx, you actually get back DOM elements because Morph DOM deals with native DOM elements, not a virtual DOM. So we can refactor our code a little bit. Our routes, I think they get the state and an emit object.

I forgot actually which one comes first. I'm gonna look that up really quick. Right, the state, yeah, I get the order right, state then emit. Okay, so now what's really nice is we can't be tempted now to call up bus.on to set up some hacky listeners because we only get access to the emit function for this state management system.

So that's pretty handy. I can update the stream handling code now so that it's gonna do, I think choo.emit. Well, we don't wanna do the rendering there, but we wanna do choo.emit or app.emit, sorry, set-visitors now because the instance itself is gonna deal with that. We can get rid of our own logic cuz Choo does that.

It's one of the few things that it does. And now, instead of setting up the reducer this way, what you do is app.use. And then the app.use function, Gets state and the full event emitter, not just the emit function. So if I modify the order of the arguments in our reducer, it should work just the same.

I'm gonna go ahead and do that now. So the state was the first argument and the emitter is the second argument. And now that I've done all of that, it should work, I think, we'll see. Great, and instead of setting up the state, Choo is gonna track that itself.

So to initialize that kinda stuff, we can do that in our reducer now. So state.visitors = 0 and state.x = 0. And ideally, this is fine if you only have a couple of events. But if you have more events and they're sort of some are related and some are not, like these aren't related events, they deal with different parts of the interface.

Then you can split those out into separate files and call use on them separately to kind of give you more separation. Okay, so I guess it could emit the update. I don't think that I need to update emit that event to begin with. So if everything is working, it's kind of a big unknown.

But I'll run npm run dev, and I'll run the server again. So, Here we go. And our code still works, I think. Wait, no, it was cached. [LAUGH] Right, so one thing to be a little bit careful about is because we did app.mount body, you actually have to have a body tag in your codes.

If you see that error, this is why. I make that error all the time. So don't feel odd. Sorry, this I meant to do. This takes a selector, not a DOM element as well. I think I've already logged an issue about that, how it should do both. But for the time being, it does take a query selector.

Okay, there we go. So I don't see the h1, but I do see a button, which is good. I think it's because I might have to emit an event. Right, this should be called render now and not update. And I'll just double check that we're not doing update anywhere, okay, good.

And I think I need to update. I think I need to emit a render event right away. Okay, that works like before. And if I open a new one, We get some error in our stream. App.emit is not a function, apparently. Maybe that was an interface that it's going to have.

>> Can you just emit?
>> What's that?
>> Don't you just call emit? Cuz you are calling emit('increment-x') and just without app.emit, it's just emit.
>> Emit isn't in scope. So to make an emitter in scope, I have to do .use. I think they're gonna change that soon, too.

Just kinda going off the discussion on the IRC channel more than what the API is currently. There we go. So it basically works the same as before. So we ported our existing application into this slightly more organized, more structured way of doing it. But the important thing, I think, here is that when you use libraries like this that are really tiny, and you can kind of find the cluster of them that all tend to work relatively well together.

Then you can build these kinds of applications incrementally, which I think is a really powerful approach. Okay, so I'm gonna add all of that to the project. And I'll push it.

Learn Straight from the Experts Who Shape the Modern Web

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