Manage Application State in Gatsby with React Hooks

Jason Lengstorf
InstructorJason Lengstorf
Share this video with your friends

Social Share Links

Send Tweet

Our app is going to require sharing information across multiple components. To make this easier to reason about, we're going to use React Context and custom hooks.

In this lesson, we'll create a custom hook that will create a React Context we can use to share state across our application.

Instructor: [0:01] Because our app is going to require sharing information across different components, we're going to use state. Specifically, we're going to use React context. To do that, we're going to use a technique that I really like, which is a single file context management using React hooks.

[0:17] We're going to create a folder called hooks and the file we're going to create is a custom hook called used-twilio-video.js. Inside, we're going to pull in a handful of things from React.

[0:30] We need React itself, we need create context so that we can actually use React context. Used context, so that we can get access to the values and use reducer, which we'll use for managing the components themselves. We're going to get all of that our of the React package.

[0:45] Next, we needed to find what our default state is going to be. This will expand as we get further into our app, but to start, we're going to store the identity and the room name that is being set in our form.

[0:59] To actually set this, we need to create a reducer. The way that a reducer works is that it accepts two parameters. The first is the state and the second is an action. That acting object can be sent in with really anything we want. Typically speaking, the action is always going to include a type and we're going to follow that convention here.

[1:18] We'll run switch on the action type. In the event that the action type is join, which would be a form submission, we're going to update our state to include the original state, but we'll extend it with the identity using action identity and the room name is action.roomName. By default, we're going to just reset the state, so we'll return default state.

[1:46] In order to use this, we need a context to store them in. We'll set up a Twilio video context and that will be the result of create context. We also need to be able to provide this context to our app.

[1:59] We'll create a Twilio video provider and that will be a React component that accepts children and it will return the Twilio videoContext.provider. The value is going to be the result of used reducer passing in the reducer function that we wrote and the default state as a starting point. Inside, we'll give it a children.

[2:24] In order to actually use this in our app, we don't want to just set it around our layout because every time the Gatsby changes pages, it will remove that layout component and remount it. We actually want to wrap the root component in Gatsby, so that we don't loss our context.

[2:39] We're going to use the wrapRootElement helper in Gatsby. We're going to write the function here, so that we can use it in two places without having to write a function twice. We're going to set up element and that will be whatever Gatsby's root element is.

[2:54] We can use the Twilio video provider component that we just created and pass in the element. Now, our entire Gatsby app is going to have access to this Twilio video context. We still need to declare that, but we're ready for it now.

[3:08] Finally, we're going to set up the used Twilio video custom hook. That's not going to accept any arguments, but it will get the state and a dispatcher from the context. We'll use context and put in Twilio video context. For now, we're going to return the state and the dispatch.

[3:30] Next stop, we need to export that as our default, so Twilio video. Then, we're going to make sure that we're actually using this. We're going to create a new file at root called gatsby-browser.js. We will export the named wrapRootElement function from source hooks used Twilio video.

[3:55] I'm going to copy that and we're going to create another file at root called gatsby-ssr for server side rendering and we'll do exactly the same thing. The reason these files are different is that we may want different behaviors between the browser render and the server side render. In this case, we don't but that's why there's two files instead of just one.

[4:15] Once we've created these files, we need to actually use this hook. We're going to go into our join component and we're going to set it up to save the identity when we submit this form.

[4:26] First, We're going to import this custom hook, so import used Twilio video from hooks used Twilio video. Above our state here, we will get the state and the dispatch out of used Twilio video. Then we're going to create a new function. This function is going to be called handle submit and it will accept an event.

[4:50] Right out of the gate, we want to prevent the default. We don't want the form to refresh the page, which is what the default form submission would do. Instead, we want to dispatch an action with a type of join and then we want to pass in the identity and the room name.

[5:06] To make sure that this thing is working, we will set up a dump of the state. We'll stringify the state with null and to for formatting and then bring it all together by setting up an onSubmit handler that will use handleSubmit. Then we can update this label to say, "Which room do you want to join?"

[5:29] In order to make sure this works, we have to stop our browser and then start it again, so yarn develop. That'll cause it to pick up the Gatsby browser and SSR changes. Once the server starts, we'll see that the state is now logged on the screen here. If I add a test name and room, when I submit this it'll update the state. Now we can see that our global state is tracking properly.