Transcript from the "React Context" Lesson
>> Now there are several ways to handle data in your React Native app, so you probably have already heard of Redux, it's kind of the go-to way. In this workshop, we are going to use React context which is a built-in way in React to handle global state. Just as a side note, if you are going to use Redux for your project, I strongly recommend you check out Redux Toolkit, which basically gives you all the power of Redux, but with very, very little boilerplate, also is fully typed with TypeScript.
[00:00:34] So it's basically magic. However, in this project we're going to be exploring React context. Now, React context basically the way it works is you wrap a context around a section of your app or you can wrap it around your whole app. And then basically, you pass down specific elements through the context and all the items that you're passed down can be then used or by all the children inside your app.
[00:01:04] Now context has two parts, there is a provider and a consumer So, the provider is this top-level component and this is where we also store the data. And then the consumer is something that can consume all the data within the provider from any row in the app component tree.
[00:01:19] So, you don't need to any prompt chilling. So, this is handy for us because if you look at our app, we would like to be entering our data from the homepage, but really want the data history to appear on the history page. And if you go to the navigation, oftentimes navigation, we couldn't even pass these down as probes because home and history are adjacent in the component tree.
[00:01:45] So that's why we have to use something like context or Redux. So to start, let's create a provider. So I'm going to create one top level context. So in a source directory, let's create a new file and let's call it App.provider.tsx. And here let's create a new context.
[00:02:14] So let's do const app, I need to check if it was capital or not. Okay, it was. So let's create a new context. So let's do const Appcontext = createContext, then create context is imported from React. And here we need to pass in a default value and also the type for it.
[00:02:43] So let's start with AppcontextType. And let's just say greeting, and I'm gonna just say hello. And I'm going to pass this context type here as we did with use state and we also need to pass in an initial value. So let's do, so this is a type, so this should be greeting string.
[00:03:12] Here we do greeting hello. All right, so now we have an Appcontext and we have an initial value, next thing we need is a provider. So this is the bit that's exported from the app provider, so let's do export const AppProvider. So this will be a React.FC and we're going to return Appcontext.Provider.
[00:03:52] And so basically, the purpose of this component is that we're going to wrap it around where we want our context to be. So we're going to take the children, so anything that's inside it, and we're going to just pass the children down. And lastly, we need to give the context a value.
[00:04:14] So the value in a provider is basically what's the current value of the context is. So this is the path that will be available for all the children to use. So we'll do value and then this needs to match the syntax, so we'll do greeting hello. And lastly, we should also import react if we're using JSX.
[00:04:43] All right, so now this is all set up. Now let's go to where we want this app provide it to be. So in our case, let's go to the top level. So I'm going to go to App.tsx and I'm going to about this in the AppProvider. Cool. So now, this means that this value that we're passing to our app provider will be available for anything that's inside the app provider.
[00:05:24] So all of our screens will have access to the same instance of that value. So usually, I create a convenience function in my provider for using it, so there's a use context hook. So I will do export const useAppContext. And the way you use context is you use context.
[00:05:50] UseContext, which is important. Sorry, let's do React.useContext. And we pass in the context you wanna use, in our case, it's the app context. So you can have multiple contexts within your app. So in this case, you could have user context, or theme context, or authentication context. And now from any component, so let's, for example, go to our history screen.
[00:06:25] We can do const Appcontext = useAppContext. And I have a hover over this, you'll see that, that need to give me the return value. Yeah, we'll see that this is of type app context type, which means that it has a greeting in it. So in history, instead of logging out history, I can do AppContext.greeting and now I can see that this says hello.
[00:06:59] So if I had more things here, hello world, it will update. And the cool thing about that is that we can use the same thing on any component without having to pass this down. So for example, if I went to the Analytics tab that we haven't used, this exact same thing will work here, so const appContext = useAppContext.
[00:07:27] If I did appContext.greeting, you can see that so I'm going home, history says hello world. And analytics also says hello world, so they have access to the same instance of context. So I'm just going through about this from the analytics screen. So what we want to use our context for is basically to pull out this mood list item into context, so we could access the mood list from both pages.
[00:08:09] So, let's do this now. Let's go to the home screen. Okay, let's open the home screen where we currently have the mood list and handle select mood. And I'm going to copy both this and go to the app provider. And this is just a React component, so I'm going to paste them here, so we got MoodList and also SelectMood.
[00:08:40] I'm going to import. And I wanna both of these down so they could be accessed by any component. So let's do moodList list and SetMoodList. And obviously, now our context type has changed, so I need to update this. So moodList is now an array of moods option with timestamp.
[00:09:13] And handle select mood is a function that takes in a mood, which is a mood option type and returns nothing. So one thing is that you need to provide a default value for all these. So we'll do moodList which is just an empty array and handleSelectMood, which is a no function.
[00:09:44] Excellent, so now both moodLists and the handleSelect functions are available within our context. So, now if we go to home. Let's delete this and use AppContext instead. So, let's do AppContext. UseAppContext. And here we have the mood picker for handleSelectMood, we'll instead pass appContext.handleSelectMood. And I'm going to copy this moodList away from the app screen because we don't want it to be here.
[00:10:28] And instead let's open history screen. So we already have AppContext here, and we want to. Do AppContext.moodList, so we wanna copy this bit. And we wanna map them to mood item, let's make sure this is important. And this doesn't need to be in text. All right, so in our home screen, all we're doing is we're accessing the app context, passing in the select.
[00:11:13] And in history, we're also passing like accessing our context and we're just using that to access AppContext.moodList to map a route and render each of the mood items. So let's see if this works. So I'm gonna choose some mood items. Yay, it's in the select screen, I'm gonna add extra celebratory emoji for that.
>> Say I'm recording my mood every day for a few days, and I traveled from London to San Francisco, and then recorded my mood in San Francisco then came back to London. How would we adjust the time and show VST for all of my moods in PS or PCT anywhere there is timezone?
[00:12:19] As we still a point in time, so you wouldn't have like dates that are like all over the place. But to actually say that, this date was recorded in a different timezone, I think you need to add the actual timezone information on the date. Yeah, I think that's how I would do it.
>> Maybe recording it in UTC or something
>> Is the app context type that you just implemented the interface?
>> Is the app context type and interface? It's not. You could use interfaces, so I wanted to keep this as simple as possible, so you could use an interface for this, we could do this. And that would work, that's valid.
[00:13:56] There are some differences with how interfaces work versus how types work. And I think types are easier to work with, so I don't generally use interfaces. One thing with interfaces is that you could have two interfaces with the same name. So let's do greeting and strength, all right?
[00:14:16] And then what actually would happen is that because these are two interfaces with the same name, they kind of get combined like in your type, which I think is quite unexpected. And if you use type, well, it's a feature, right, if you use object-oriented programming especially, but if you use type, you wouldn't be able to have two types with the same name.
[00:14:41] So in general, I kind of stick to types, I think they're a bit more straightforward.