LeoM
LeoM

Reputation: 110

How to properly fetch data on user click?

I'm trying to display a menu with three tags Streaming,On Tv and In Theaters similar to what you can find on https://www.themoviedb.org/

The default data that is displayed is the Streaming section, which is receiving JSON from getStaticProps. I only want to fetch On Tv and In Theaters endpoints if the user clicks on it, and later cache that information. This is my code so far (only On Tv example, though In theaters would be the same):

import useSWR from 'swr'
import React, { useState } from "react";

const fetcher = async (e) => {
    const res = await fetch(e);
    const data = await res.json();
    return data
};
  
const Trending = ({data}) => {
    const [media, setMedia] = useState(data); //data used to display shows/movies
    const [onTv, setOnTv] = useState(null);
    
    const [shouldFetchTv, setShouldFetchTv] = useState(false);
    const urls = [
        `https://api.themoviedb.org/3/tv/on_the_air?api_key=${process.env.NEXT_PUBLIC_API_KEY}&language=en-US&page=1`,
        `https://api.themoviedb.org/3/movie/now_playing?api_key=${process.env.NEXT_PUBLIC_API_KEY}&language=en-US&page=1&region=US`
    ]

    const tv = useSWR(shouldFetchTv && urls[0], fetcher);
    const tvResult = tv.data;
    
    const handleTv = () =>  {
        onTv ? setMedia(onTv) //if onTv has data then just set it
        :
        setShouldFetchTv(true); //fetches endpoint on users click
        setOnTv(tvResult); // caches the data
        setMedia(onTv); //sets media object with the cached data
    }

   (...Some more code)
       <div onClick={handleTv}>  
          <h1>On Tv</h1>
          </div>

The problem is that onTv object doesn't get properly defined on the first click, but on the third. I've been trying to implement useEffect to no effect (no pun intended), but I'm still learning hooks so maybe I'm missing something. How can I get it to work properly?

Upvotes: 0

Views: 575

Answers (1)

OwnageIsMagic
OwnageIsMagic

Reputation: 2299

On first click shouldFetchTv is false and onTv is null. shouldFetchTv sets to true

On second click shouldFetchTv && urls[0] becomes true and async request is sent, tvResult = tv.data is null because it async

On third click you send second request and result of first is available so it sets onTv

On fourth click onTv is not null

Because useSWR is using browser cache async result is available on third click

Upvotes: 1

Related Questions