Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Miguelcds/Recipe-Hub/llms.txt

Use this file to discover all available pages before exploring further.

Recipe Hub uses two custom hooks to encapsulate all async data fetching. This keeps pages and components free of useState/useEffect boilerplate and makes the fetching logic independently testable.
Both hooks reset their state (recipes, errors) before each fetch. This prevents stale data from a previous search appearing briefly while a new request is in flight.

useRecipes

Manages fetching multiple recipes — either by search query or as a random selection. Used by the Home page.
Import as a default: import useRecipes from '../hooks/useRecipes'

Source

src/hooks/useRecipes.js
import { useState } from 'react'
import { getRecipeByName, getRandomRecipes } from "../services/api";

const useRecipes = () => {
  const [recipes, setRecipes] = useState([])
  const [loading, setLoading] = useState(false);
  const [apiError, setApiError] = useState("")

  const fetchRecipes = async (search) => {
    setLoading(true)
    setRecipes([]);
    setApiError("");
    try {
      const data = await getRecipeByName(search)
      setRecipes(data)
    } catch (error) {
      return setApiError(error.message)
    } finally {
      setLoading(false)
    }
  }

  const fetchRandomRecipes = async () => {
    setLoading(true);
    setApiError("");
    setRecipes([]);
    try {
      const data = await getRandomRecipes();
      setRecipes(data);
    } catch (error) {
      setApiError(error.message);
    } finally {
      setLoading(false);
    }
  };

  return { recipes, loading, apiError, fetchRecipes, fetchRandomRecipes, setApiError }
}

export default useRecipes;

Return values

ValueTypeDescription
recipesArray<{ id, name, picture, category }>Normalized recipe objects from the last successful fetch
loadingbooleantrue while a fetch is in progress
apiErrorstringError message from a failed fetch, or empty string
fetchRecipes(search: string) => Promise<void>Fetches recipes matching the search query from TheMealDB
fetchRandomRecipes() => Promise<void>Fetches 9 random recipes in parallel
setApiError(msg: string) => voidAllows the SearchBar component to set a validation error without triggering a fetch

fetchRecipes vs fetchRandomRecipes

Call fetchRecipes(query) when the user submits a search term. It calls getRecipeByName and populates recipes with all matching results. If no results are found, the service throws and apiError is set.

useRecipeDetail

Fetches and manages the state for a single recipe. Used by the RecipeDetail page, which passes the id URL parameter directly to this hook.
Import as a default: import useRecipeDetail from '../hooks/useRecipeDetail'

Source

src/hooks/useRecipeDetail.js
import { useEffect, useState } from "react"
import { getRecipeById } from "../services/api"

const useRecipeDetail = (id) => {
  const [recipe, setRecipe] = useState(null)
  const [loading, setLoading] = useState(false)
  const [apiError, setApiError] = useState("")

  useEffect(() => {
    if (!id) return
    const fetchRecipe = async () => {
      try {
        setLoading(true)
        setRecipe(null)
        setApiError("")

        const data = await getRecipeById(id)
        setRecipe(data)
      } catch (error) {
        return setApiError(error.message)
      } finally {
        setLoading(false)
      }
    }

    fetchRecipe()
  }, [id])

  return { recipe, loading, apiError }
}

export default useRecipeDetail

Return values

ValueTypeDescription
recipeobject | nullFull recipe detail object, or null before the first fetch completes
loadingbooleantrue while the fetch is in progress
apiErrorstringError message if the fetch fails, otherwise empty string

Automatic re-fetch on id change

The useEffect dependency array includes id. If the user navigates directly from one recipe detail page to another (changing the :id URL param), the hook automatically re-runs the fetch for the new ID without requiring a full page reload. The guard if (!id) return at the top of the effect prevents a fetch from firing when id is undefined — for example, during the initial render before the router has resolved the param.

Build docs developers (and LLMs) love