I am struggling to understand exactly what is going on with the Youtube API.
It seems the application I developed in React continuously makes requests to the Youtube API even after initial render is done. I had to go back and refresh my understanding of useEffect and realized that it was set up correctly and then even after I implemented a way to cache the initial requests, it seems to still be making requests from what I can tell in the network tab and obviously thats eating up my quota.
I started to notice it after I developed a custom hook to store my fetching of 8 very specific videos from YouTube. This is my useVideos
custom hook:
import { useState, useEffect } from "react";import youtube from "../apis/youtube";const useVideos = () => { const [videos, setVideos] = useState(() => { const cachedVideos = localStorage.getItem("cachedVideos"); return cachedVideos ? JSON.parse(cachedVideos) : []; }); useEffect(() => { if (videos.length === 0) { fetchSpecificVideos(); } }, []); const fetchSpecificVideos = async () => { try { const videoIds = ["VIDEO_1","VIDEO_2","VIDEO_3","VIDEO_4","VIDEO_5","VIDEO_6","VIDEO_7","VIDEO_8", ]; const videoData = []; for (const videoId of videoIds) { const response = await youtube.get("/videos", { params: { id: videoId, part: "snippet", maxResults: 8, }, }); if (response.data.items && response.data.items.length > 0) { videoData.push(response.data.items[0]); } } setVideos(videoData); localStorage.setItem("cachedVideos", JSON.stringify(videoData)); } catch (error) { console.error("Error fetching videos:", error); } }; return [videos, fetchSpecificVideos];};export default useVideos;
NOTE: I did replace the actual ids with what you see above.
In my actual api file I have the following:
import axios from "axios";const KEY = "my-youtube-api-key";export default axios.create({ baseURL: "https://www.googleapis.com/youtube/v3", params: { part: "snippet", maxResults: 8, key: KEY, },});
I am adding a screenshot of the network tab, perhaps I am misunderstanding what is going on, but to me that looks like a lot of requests for just 8 very specific videos that load once on app render. This is happening with or without the localStorage
implementation:
I am wondering if this is a case for some type of memoization.
A colleague suggested that if multiple (N) components are using the custom hook of useVideo
then all of those components will initiate the asynchronous request, that makes sense, however, only the parent App component is making use of that custom hook. I am posting the App.js component here:
import React, { useState, useEffect } from "react";import Header from "./Header";import VideoList from "./VideoList";import VideoDetail from "./VideoDetail";import useVideos from "../hooks/useVideos";const App = () => { const [selectedVideo, setSelectedVideo] = useState(null); const [videos, fetchSpecificVideos] = useVideos(); useEffect(() => { if (videos.length === 0) { fetchSpecificVideos(); } }, [videos, fetchSpecificVideos]); useEffect(() => { if (videos.length > 0) { setSelectedVideo(videos[0]); } }, [videos]); return (<div className="ui container"><div className="ui inverted menu"><Header /></div><VideoList onVideoSelect={setSelectedVideo} videos={videos} selectedVideo={selectedVideo} /><VideoDetail video={selectedVideo} /></div> );};export default App;
The custom hook is not being utilized in any other components.