Advanced Hooks 8 exercises

Handling Different State Values with Discriminated Unions

The solution to handling different states is very similar to one we've covered before with a discriminated union.

We have three different states to represent, each with different properties:

  1. Status Loading - has no error
  2. Status Loaded - has no error
  3. Status Error - has an error

We can cre

Loading solution


00:00 The solution here is very similar to one that we've covered before with a discriminated union. You can think about this in that we have three different states that we need to represent here, each with different properties. We have a status Loading which has no error, we have a status Loaded which has no error, and we have a status Error which has an error.

00:17 So we can create a discriminated union. Let's say type state equals status Loading, or status Loaded, or status Error.

00:33 And with status Error, we want to make sure that you have to pass in error, which is going to be a type of error. There we go. Nice and simple. Now this error, is this not correct? Error does not exist on type status action. Of course, I actually need to pass it in to the useState here.

00:50 I was thinking TypeScript was a little bit too magic there. So now our state is state, and our state is a lot more descriptive. We can shorten this if we want to. We can say status Loading or Loaded here.

01:05 This is kind of neat actually, because now we're capturing two statuses in one little area there, both of which have the same exact props but very different meaning to our UI. One shows a loading spin and one doesn't. And this one is the only one with status Error here. So this is probably the most terse way to do it.

01:23 And now everything works as expected. If I don't pass an error here, it's going to yell at me because error is missing and blah, blah, blah, blah, blah. And this one's going to yell at me for the same reason, except I have passed an error when I shouldn't have.

01:35 So this is a really, really nice way, and I think a lot of people overlook this as a power that you can do with useState. We often reach for useReducer in these situations because we think, OK, we need more than one property to track. Let's use useReducer here. But actually useState can handle a lot of different things that you throw at it,

01:53 and having a discriminated union here makes useState a lot smarter and pretty robust.