So after we've done that, we need to kind of work with our state updater a little bit. So setState is going to take an updater function and basically just run that updater function with the existing state and return the new state, kind of like a reducer. Or if you've used setState before with React it's a lot like that.
Next up we have our fetch function, and our fetch function is going to be async for now. What this fetch function does is, the first thing we want to do is use our new setState function on the query to setIsFetching to true and clear out the error. Then we're going to, in a try-catch block, try and call our query function, so we'll use await here, get the data from the query function, and then if everything succeeds we're going to put status success and add our data. And then in our catch, if we have an error, we're going to do the same thing, just status error with the error. And finally, literally, finally, we're going to set queryPromise to null and query.setState we're going to setIsFetching to false.
So this quirky.promise doesn't exist yet, but we are going to need it. So let's set the promise to null up here, out of the gate. And what this is going to do is allow us to start setting up some de-duping. So if the query function is already being run or it's in progress, we don't want to fire it off again. We're going to use that query.promise property to do some promise magic. Instead of making this Fetch Function async here, we're going to wrap it in some other logic. We're going to wrap it in this block right here. So if there's not a promise yet, we're going to assign that promise to a new promise coming from this asynchronous function. And we can just dump all of our existing logic into that function right there. So it says if there's no promise, then kick off a new Fetch Function and assign it to the promise. And so that any other times we call Fetch if there already is a promise, we are just going to return it right here. So if not promise, then we'll just say return query.promise. And that takes care of our de-duping problem, which is a pretty slick and easy way to do that. We want to make sure that in the finally, whenever it finishes, we set that query promise to null so that we can fire it off again.
We can't wire this create query function right up to our useQuery hook. We have to allow the queries to be shared by multiple instances of useQuery, so we're going to have to create some subscriber support for all of this, and we're gonna start doing that in our query, in our createQuery function here. I'm going to create a new method on here called subscribe. It's going to take a subscriber, which is just an object for now, and we're gonna push that onto query.subscribers, so I'm going to need subscribers up here is going to be an array. And then it's going to return an unsubscribe function, which will just remove that from the subscriber list when we call it. And we also need to update our setState function right up here so that whenever we call setState we notify all the subscribers. We loop through them and we call subscriber.notify. And I'm just gonna move this down here, so we keep things organized.
Comments