Check out a free preview of the full A Tour of JavaScript & React Patterns course:
The "Provider Pattern Solution" Lesson is part of the full, A Tour of JavaScript & React Patterns course featured in this preview video. Here's what you'd learn in this lesson:

Lydia codes the solution to the Provider Pattern challenge.

Get Unlimited Access Now

Transcript from the "Provider Pattern Solution" Lesson

[00:00:00]
>> So the first thing that I like to do is to put all the providers anything with context in a separate folder called context. You don't have to do that, it's just what I personally prefer. If you like anything else, feel free to do that. Now here, I'm going to do it listings provider.

[00:00:16] And in here I'm just going to import react from react. I'm also going to import the use listing, because this is essentially what we'll be using afterwards use listings. Hopefully I, yep. Now, I'm going to tap that listings provider. And this one I use this use listings hook, cuz it needs to pet those listings.

[00:00:38] I'm just gonna say if no listings then return no, or loading spinner, I don't have that component right now. Normally I would've added a nice spinner. And otherwise return the context of we're going to create now. So, here's like constant listings context is react dot create context. And the initial value is no, like we don't have anything yet.

[00:00:59] It's kind of just like an empty object. So, here we can say okay, so, from this context, I want to have the provider. And the value that we wanna pass to the consumers are the listings, in here I'm going to use prop set children, and then listings context up provider, boom.

[00:01:20] Now, like a set before I like to create a custom hook for this. So maybe like- function use listings context and then return reacts dot use context. So this hook lets us consume the context that we're providing to that children off their listings provider, so that is listings context.

[00:01:41] Cool. Now, the parent most component that wraps both the input and the listings is an app. So, we need to go back here and import this provider from context listings, provider listings provider not listing and we are just going to wrap that here. Cool. So now we just need to update the input component.

[00:02:08] I don't want it to use listing hook instead, I wanted to use the Use listings context, use, sorry, listing provider. So in here, I get this, it is a named export, and I also have to change that in listings. So I'm gonna say use listing context from context listings provider or listings context and then we're going to use that here.

[00:02:39] Now, I don't really have to show that anymore because we that provider already renders know that if there is no data and that reps that component. So right now we have access to the listings through this context that we provide in this provider. So we're only calling useless things once and the data that we get from that we are passing to both, well, to any child component that would like to consume it.

[00:03:04] But in is case, we're only consuming it here and input and then again in enlisting. So the nice way of sharing data across multiple components and making sure that especially if you're fetching data or something to minimize like the amount of API calls. Because that can get pretty both laggy and expensive as if it's your own API stuff like that.

[00:03:25] So yeah, this is a pretty easy way to use the provider pattern and to share data across multiple components. Any questions about the solution?
>> Yeah, I got one question that you mentioned re-renders and if I'm a consumer, and let's say the context is pretty complex it's got a lot of returns, right?

[00:03:43] But I'm only consuming one of them and context updates something else that I'm not consuming, am I not gonna re-render or is it an all or nothing thing with context?
>> As far as I know so for example right now we're actually returning listings, but maybe this is like an object I just have to change this real quick otherwise it's guaranteed freak out events listings.

[00:04:05] But maybe we also had another value in here. I don't know, it could be data set data is react use state and let me know if this doesn't answer your question, but maybe we also have like data in here. Now, if data updates, but the input is only consuming listings it will not re-render, so only the consumers that also use that data will re-render.

[00:04:26] I may be mistaken here, but this is the last thing that I learned. So, if that's not right, do let me know that. Yeah, it will only render if you're actually consuming the updated value. Any more question?
>> So this is using like the built in React stuff like create context and whatever.

[00:04:46] Is there kind of a more generic idea of a provider?
>> Provider patterns?
>> Pretty much like at least in the context of React you would just always-
>> Yeah, when we're talking about React and we're talking about the provider pattern this is definitely pattern that we're thinking about.

[00:05:01] I think in like in general let's see what like defines a provider pattern, I don't know if there's like make data available to multiple child components. So, it could really be any like wrapped component, I guess it passes data in like an easy way to multiple child components.

[00:05:18] But when talking about React and I'm not entirely sure like what defines the provider pattern maybe in other languages you can use like other tools. I'm not entirely sure I don't dare to make any statements there. But like, no, that's not true. Yeah, with React, it's always with like the context API.

[00:05:34] And if you wanna use hooks like I did here, use hooks but you don't have to, so cool.
>> There was a question online that was in a complex app, you might have lots of providers. So you just Brett, do you wrap your app with all providers or just certain components in that case where you've got a bunch?

[00:05:55]
>> Yeah, I mean, in this case, I'm wrapping it in within this app just because like that's the parent most component that shares children that both need this input. But always try to make sure and also like you can read this multiple times if the data doesn't have to be shared.

[00:06:11] For example, if I read this and like the input listings, now this will create two different providers for each of them item. So like I could, if you want to reuse certain data in like smaller sections of your application, you can totally do that. And that's also obviously, way more performant like try to make sure that you're only wrapping the parent most component that or the kind of the common ancestor component.

[00:06:35] I don't know if that makes sense. But don't unnecessarily wrap your application in all those providers, even though it will only update if it consumes it it can still cause like unexpected re renders. And it also makes it like a lot more readable to understand which component parts are consuming certain data, yeah.

[00:07:00]
>> I'm a bit lost here. When previous lighting if I'm right whenever I used a provider the child covenant was interested in has to have a consumer portion of it.
>> Yeah, so that was, let's see. So you can either use it, I guess is what you're referring to, right?

[00:07:20] Yes. So you can either use this or you can use the use context hook. So this is like, either or, but personally, I prefer to use the use context hook just because it's smaller. It's personally more readable to me, but feel free to use that this render props pattern with a consumer.