This video is available to students only

Frontend State

Handling State in React

Handling state in React is a problem with many solutions. There are several libraries that enable different paradigms. This booking flow will only have very limited state which means that the built-in Context will be sufficient for our needs. We will combine it with React Query because it comes built in with tRPC, which we will use for API calls, but we'll get to that later.

Now, there are two distinct sets of state that we want to keep track of here: the "navigation", i.e. which page the user is on, and the actual data that the user is entering.

You're going to create a file that contains your Context and a little helper hook that encapsulates the logic of keeping this state up to date. Create bookingFlowContext.tsx in the src folder and add the following code:

Let's break this down. The type BookingFlowState is empty for now, but it will contain the fields that the user will fill in. The outer type, BookingFlowContext, contains that state as well as some functions that relate to navigation. We will get access to these through the useContext hook.

The context is created with a default value that throws an error if you try to access it before it has been set. There is no way for the type system to ensure that a component that relies on the context is actually wrapped in a provider. That's a shame but this approach will at least give you an easily understandable runtime error if you happen to do so by accident. An alternative would be to allow undefined as a value for the context, but that would then require defensive undefined-checks everywhere you use the context. Ultimately, this is down to personal preference, but I am generally in favor of fail-fast over defensive programming.

The useBookingFlow hook is the one that you will use to apply the context. It takes an array of components making up the pages of your booking flow. The hook returns the current page, the index of the current page, and a function to set the current page.

Use the hook like this in NewBooking.tsx:

Okay, so this gives you the same functionality as before, but now you have a nice way to keep track of the state of the booking flow. You can also easily add more pages to the flow by adding more functions to the array. You'll move the back/next buttons into the pages themselves so that you can disable and enable them depending on the current page. However, you can add a progress indicator at this level. We'll create a bunch of circles with numbers in them to show where in the flow the user is.

For this, you need to apply conditional classNames. That can be easily done with string concatenation or interpolation, but a helper library quickly becomes nice to have. The one I tend to use is called clsx. It's very simple and easy to use. Install it with npm i clsx and update your NewBooking.tsx file like this:

Screenshot

This lesson preview is part of the Fullstack Typescript with TailwindCSS and tRPC Using Modern Features of PostgreSQL course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

Unlock This Course

Get unlimited access to Fullstack Typescript with TailwindCSS and tRPC Using Modern Features of PostgreSQL, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course Fullstack Typescript with TailwindCSS and tRPC Using Modern Features of PostgreSQL