Hone logo
Hone
Problems

Building a Reusable useFetch Hook in React with TypeScript

The useFetch hook is a common pattern in React applications for simplifying data fetching. This challenge asks you to implement a custom useFetch hook that handles fetching data from an API endpoint, managing loading states, and handling errors gracefully. A well-implemented useFetch hook promotes code reusability and improves the overall structure of your React components.

Problem Description

You need to create a custom React hook called useFetch that takes a URL as an argument and returns an object containing the following properties:

  • data: The fetched data from the API. Initially undefined.
  • isLoading: A boolean indicating whether the data is currently being fetched. Initially true.
  • error: An error object if an error occurred during the fetch. Initially undefined.
  • refetch: A function that can be called to manually trigger a re-fetch of the data.

The hook should:

  1. Fetch Data: Upon initial render, the hook should initiate a GET request to the provided URL.
  2. Manage Loading State: Set isLoading to true before the fetch begins and false after the fetch completes (regardless of success or failure).
  3. Handle Success: If the fetch is successful, update the data property with the parsed JSON response.
  4. Handle Errors: If the fetch fails, update the error property with the error object.
  5. Refetch Functionality: The refetch function should allow the component using the hook to manually trigger a new fetch request to the same URL.
  6. Dependency Array: The hook should only re-fetch data when the URL changes.

Examples

Example 1:

Input: URL = "https://jsonplaceholder.typicode.com/todos/1"
Output:
{
  data: { userId: 1, id: 1, title: 'delectus aut autem', completed: false },
  isLoading: false,
  error: undefined,
  refetch: () => {} // A function to trigger a re-fetch
}
Explanation: The hook successfully fetches data from the provided URL and populates the `data` property. `isLoading` becomes false, and `error` remains undefined.

Example 2:

Input: URL = "https://jsonplaceholder.typicode.com/nonexistent-endpoint"
Output:
{
  data: undefined,
  isLoading: false,
  error: Error: Request failed with status code 404,
  refetch: () => {}
}
Explanation: The hook attempts to fetch data from a non-existent endpoint. The fetch fails, `isLoading` becomes false, and the `error` property is populated with an error object.

Example 3:

Input: Initial URL = "https://jsonplaceholder.typicode.com/todos/1", Subsequent refetch() call
Output: (After refetch())
{
  data: { userId: 1, id: 1, title: 'delectus aut autem', completed: false },
  isLoading: false,
  error: undefined,
  refetch: () => {}
}
Explanation: The `refetch` function is called, triggering a new fetch request. The hook fetches the data again and updates the `data` property.

Constraints

  • The URL must be a valid string.
  • The hook should use the fetch API for making the HTTP request.
  • The hook should handle network errors gracefully.
  • The hook should parse the response body as JSON.
  • The refetch function should not trigger a fetch immediately upon being called; it should only initiate the fetch when actually invoked.
  • The hook should be written in TypeScript.

Notes

  • Consider using async/await for cleaner asynchronous code.
  • Think about how to handle potential errors during JSON parsing.
  • The refetch function should maintain the same URL as the initial fetch.
  • The initial isLoading state should be true to indicate that the data is being fetched.
  • Focus on creating a reusable and well-structured hook. Avoid hardcoding any specific API endpoints within the hook itself.
Loading editor...
typescript