skip to Main Content
import { useCallback, useEffect, useState } from "react";

const [isLoading, setIsLoading] = useState(false);
const [videos, setVideos] = useState([]);
const [nextToken, setNextToken] = useState(null);

useEffect(() => {
  getVideos();
}, []);

const getVideos = async () => {
  try {
    const url = nextToken
     ? API_URL+ "&token=" + nextToken
     : API_URL;
    console.log("Fetching data from:", url); // not appending API_URL 

  const data = await fetch(url);
  if (!data.ok) {
    throw new Error("Failed to fetch data");
  }

  const json = await data.json();
  setNextToken(json.nextPageToken);
  console.log(nextToken);
  setVideos((prevVideos) => [...prevVideos, ...json.items]);

} catch (error) {
  console.error("Error fetching data:", error);
} finally {
  setIsLoading(false);
}

In above code nextToken is always null although getting successful response in json.nextPageToken. it is not appending with "API_URL+ "&token=" + nextToken"

2

Answers


  1. The useState set method is executed asynchronous, therefore a console.log which is executed right after calling that function, will never output the new state. Instead you could pass a function to the useState set method, which logs the new state before setting it.
    So instead of

    setNextToken(json.nextPageToken);
    console.log(nextToken);
    

    that would be

    setNextToken(() => {
        console.log(json.nextPageToken);
        return json.nextPageToken;
    });
    

    Look here in the docs for more information.

    For that to work you will also have to initialize nextToken and setNextToken for example like this:

    [nextToken, setNextToken] = useState(null);
    
    Login or Signup to reply.
  2. Your code seems to have a few problems.

    • setToken(null) to initialise the token state, but then you’re talking about nextToken, which hasn’t been initialised. That’s how you should initialise nextToken if it’s meant to be like token.

    • Asynchronous Data and State Update: After running setVideos, you’re changing the nextToken state. Although, because React updates states asynchronously, the new value of nextToken won’t be available right away after calling setNextToken. You can now simply use the new json.nextPageToken in the URL construction instead.

    • Loading State-Based Conditional Rendering: In the end block, you’re making isLoadingfalse. You are not setting it to true anywhere in the code, though. Setting it to true before getting data is important, and returning it to false after fetching is complete, whether it worked or not.

    Here is the updated code:

    import { useCallback, useEffect, useState } from "react";
    
    const [isLoading, setIsLoading] = useState(true); // Set initial loading state to true
    const [videos, setVideos] = useState([]);
    const [token, setToken] = useState(null);
    const [nextToken, setNextToken] = useState(null); // Initialize nextToken state
    
    useEffect(() => {
      getVideos();
    }, []);
    
    const getVideos = async () => {
      try {
        const url = nextToken
         ? API_URL + "&token=" + nextToken // Use updated nextToken here
         : API_URL;
        console.log("Fetching data from:", url);
    
        setIsLoading(true); // Set loading state to true before fetching data
    
        const data = await fetch(url);
        if (!data.ok) {
          throw new Error("Failed to fetch data");
        }
    
        const json = await data.json();
        console.log("Response:", json);
        setNextToken(json.nextPageToken);
        console.log(nextToken);
        setVideos((prevVideos) => [...prevVideos, ...json.items]);
    
      } catch (error) {
        console.error("Error fetching data:", error);
      } finally {
        setIsLoading(false); // Set loading state back to false after fetching data
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search