00:00:02 In the previous lesson, we implemented this fetchMovies function.
00:00:07 But before diving into using it, which involves API calls, using the useEffect hook, managing loading and error states, and potentially cluttering our
00:00:17 code with repetitive logic, there's a more efficient approach.
00:00:21 Instead of repeating the same code for every request, we can improve this process by using something known as a custom hook.
00:00:29 This hook will handle fetching the data in a clean, reusable, and scalable way.
00:00:35 So let's create a new file within the services folder, and let's call it useFetch.ts.
00:00:43 And we can develop that custom hook.
00:00:45 This hook will allow us to handle API requests without cluttering the components by abstracting away the logic for fetching the data,
00:00:54 managing loading and error states.
00:00:56 And it'll even provide us with a way to manually trigger a refetch when needed.
00:01:01 Let me show you how it'll look like.
00:01:03 We can say const useFetch.
00:01:05 Again, notice the keyword use indicating that it is a hook and we can make it equal to a function call and we can make it equal to an arrow function.
00:01:15 Now bear with me for a second.
00:01:18 The useFetch hook will accept the fetch function as a parameter.
00:01:24 Okay?
00:01:25 So what can this fetch function be?
00:01:27 Well, it can be like fetchMovies.
00:01:30 Or it can be something else.
00:01:31 Maybe like fetchMovieDetails.
00:01:34 Whatever it is, we're going to pass it into this useFetch call.
00:01:39 So it'll look something like this, useFetch fetchMovies.
00:01:43 We immediately have to let it know that the first parameter will be that fetch function, and we need to define its type.
00:01:50 And the type will be a function that returns a promise and the promise will be of a generic type T.
00:02:01 T makes it a generic function allowing us to later on pass the specific data types that we want the function return to be.
00:02:09 It'll all make sense once we start using it.
00:02:11 We also have to add this generic T parameter here.
00:02:15 And as the second parameter, we'll pass the autofetch and make it equal to true.
00:02:19 If you don't understand what this means, specifically this promise generic parameter T, again, don't worry about it.
00:02:26 I'll explain it in more detail once we actually start using this function.
00:02:30 Great.
00:02:30 With that said, this useFetch function will have to work with some kind of data.
00:02:35 So we can create a new state called data and setData.
00:02:40 which will be equal to the useState hook and it'll be of a type T or null.
00:02:47 You define it right here before we open the function call of this function.
00:02:53 And by default, we'll set it to null.
00:02:56 Next, we need to define the loading and setLoading at the start equal to false, and also the errors.
00:03:03 constError setError is equal to the useState where the type of that state is either an error or a null by default.
00:03:13 Now that we have implemented those different states, let's create a function const fetchData, which will be equal to an asynchronous function within which
00:03:23 we can open up a try and catch block.
00:03:28 In the catch, we'll of course get the access to the error.
00:03:31 I'll shorten it for err and within it, we can set error.
00:03:37 If an error is an instance of error, then I'll just forward the entire error, else I'll just create a new error and pass in a string of an error occurred.
00:03:53 And I'll suppress the TypeScript right here for this line by saying tsignore.
00:03:57 Then we're going to also add a finally clause.
00:04:00 Finally block of code gets executed either when a try succeeds or a catch finishes.
00:04:07 Either way, we want to set loading to false.
00:04:10 But now what we care about the most is dealing with the try block, which means actually fetching the data.
00:04:16 First, we're going to set loading to true, because we want to start the loading action.
00:04:22 We're going to also reset the error to false, or rather null.
00:04:27 There is no error.
00:04:30 we can say const result is equal to await fetch function.
00:04:38 So keep in mind that this fetch function is not yet declared.
00:04:42 The fetch function will be passed through props and it can be either the fetchMovies function, which we created not that long ago,
00:04:50 or maybe another function which we'll create in the future, like fetchMovieDetails, or maybe another function which we'll create soon.
00:04:57 In any case, the function we want to call will be passed through as the first parameter to the useFetchHook, and then we'll call it right here,
00:05:06 get the results, and simply set them to the data.
00:05:09 So setData is equal to result.
00:05:12 Also, below this entire fetchData function, we can also have a reset function.
00:05:18 So const reset is equal to an error function, where we set the data to null, set the loading to false, and set the error to null as well.
00:05:28 Finally, I'll also create a useEffectHook.
00:05:31 And a useEffectHook is called when you want to do something at the start of your component load.
00:05:37 So in this case, as soon as the component loads, we want to check if autofetch is turned on.
00:05:45 That means that we want to automatically fetch the data in that case.
00:05:48 So if autofetch is true, we'll simply call the fetchData function.
00:05:53 Finally, hooks have to return something.
00:05:56 So I'll return almost everything.
00:05:58 The data state, the loading state, the error state, the refetch function, which I'll call fetchData, as well as the reset function.
00:06:08 So later on, when we use this hook, it is dealing with everything data related.
00:06:13 Fetching, loadings, errors, and finally the data that it's returning.
00:06:18 So let's say export default useFetch so that in the next lesson, we can use the useFetch hook as well as use the fetchMovies function,
00:06:28 merge them together to be able to fetch and display movies.