Advanced Redux with Redux Toolkit

Typed useSelector Hook

Steve Kinney

Steve Kinney

Advanced Redux with Redux Toolkit

Check out a free preview of the full Advanced Redux with Redux Toolkit course

The "Typed useSelector Hook" Lesson is part of the full, Advanced Redux with Redux Toolkit course featured in this preview video. Here's what you'd learn in this lesson:

Steve demonstrates one method for adding type support to the useSelector Hook. An ApplicationState type is declared and exported from the store. The drawback to this approach is the type must be imported anywhere the useSelector hook is used.


Transcript from the "Typed useSelector Hook" Lesson

>> Let's pull in the use selector cuz we're gonna come to our next problem that again, I have an elegant solution for. But first, let's suffer a little bit and we'll take a look at it, cool. So your question was like, so what's this use selector thing that I can put in there?

That's a great, why don't you ask me that question again? [LAUGH]
>> Yeah, so I have to save the crops so I can replace with use selector, right?
>> You can, we should do that. Absolutely, let's try it out. So here, I'm pulling the tasks from that contacts API that had sitting around.

So we've got use selector. And this, you can imagine what use selector takes as an argument, and why it wants one from me.
>> No, this isn't React Redux. But it is, they did a complete rewrite effectively, reactory docs had a major rewrite, I wanna say two years ago-ish, where it was completely written in TypeScript and for supporting all these hooks out of the box.

So yeah, when hooks dropped, there wasn't necessarily supporting, there had to be a lot of rethinking and what to do. And now we do have this little thing there, they're pretty nice in the sense as well and so welcome to the problem. So the normal way of just writing JavaScript is you do like, this is your entire state tree.

This is not unique to that slice. This is not anything. This is the entire state tree. And you would normally, in map dispatch props, you'd write a selector like effect. You take the thing, you'd pull the props you want, get them ready for the inside that higher order component for whatever, the presentational component was, great, awesome.

So here we've got state.tasks. This doesn't feel like I have auto complete, right? And I feel like I got a red squiggly line. And it's upset with me. It's like state is a type unknown. Cuz this selector doesn't, I mean, it came from, to your point, came from a different library, right?

It doesn't know. I guess, it has some, yeah, it doesn't know. I'm like, could it no but if it could know, they probably would have done it, right? If you rewrite an entire library just for TypeScript, so what do we do? You could say that this is the type of the entire state somewhere.

You could be like, we know what the shape of our state tree is right now cuz it's simple and small. So if I look at useSelector, unknown is what that state is most likely. So I could say that it's got tasks, and then tasks have entities, and that's an array.

Look, everything's happy, right? That seems cool, I guess. It didn't even get it totally right there but, we have to say the state is that shape. So yeah, that's fun. Anyway, you probably don't wanna do this. We can say it right here as well defining this. I'm building up for the fact that we don't have to live like this.

Cool, it's confused about everything. Cuz it just thinks it's an array of nothing, so I gotta say it's an array of tasks. Yeah, it's your first thing, it's like, you know what I'll do? I'll make a type, I'll put it in my global d.ts, and it's the shape of my state.

You could do that, you could. And guess what? Every time you add a new reducer or change the shape of your state, or just even add a property to a thing, right, you're going to have to update that in some way, shape or form, right? And so then you start to create a House of Cards of other types.

And that doesn't go super well, right? And so if only there was a way to generate a type based on whatever the end result that came out of your store was. By definition, we know the TypeScript automatically can derive the types of return values of functions, right? Under the hood, Redux has the store object that it gives you back has a dispatch method, you can guess what that does.

Also, there's one called getState. You can roughly guess what that one does, right? They got good names and so if there was only a way that we could do that, well, we can.
>> The return type of getState?
>> Yep, perfect, that was a good segue. [LAUGH] I thought the question I was like, yeah.

I set it up, you got it, perfect. [COUGH] So let's look at that inside store where I have this ready to go, and this is why I had this out of its own file. And so here I can say something type. You can call it RouteState. I like to call it ApplicationState.

I've seen a call RouteState before, that works, too. And we can say that this is the same method that we did with those actions that we're making ourselves earlier with create action to get the return type of a function. We say return type and we say, Cool. Store.

And look it's my issue.
>> Do you need to invoke it or no?
>> I don't need to invoke it. Perfect, I'm so used to calling the function, all right, cool. So now, look, that is the shape of our state. So it could be tempting to go ahead and do this.

And the temptation is good, but you can't put it in a global file because it does need this JavaScript, right? It's not something you're just defining. If you define it yourself and tried to keep it up to date manually, you can totally do that. But here, it is a thing that we have to export.

So we can go back into the tasks list at this point. And we could say that, actually, This is the ApplicationState. The red squiggles are gone. Everything is happy, life goes on. Welcome to the world where you have to import this now every time you also import your selector.

No, I don't want to live like this either. No, I'm not doing it. You can't make me.

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