skip to Main Content

I’m new to react (and web development as a whole), and I have been using ChatGPT to put much of my work together. I can’t figure out what I’m doing wrong here. I am using the movie ID to find the movie description using the TMDB API, but even thought the API calls are valid, the paragraph element I am passing the info to will not re-render. The console logs verify that the API is being called correctly.

For example: "Movie description: One morning, Jessica Holland, a Scottish orchid farmer visiting her sister in Bogotá, is woken by a loud ‘bang’. This haunting sound dispels her sleep for days, calling into question her identity and guiding her from recording studios to secluded jungle villages in an attempt to find its source."

For context, I am using nextjs.

Here is the code for the component I am working on:

import classNames from 'classnames';
import React from 'react';
import { useEffect, useState } from 'react';

export interface Info_windowProps {
    className?: string;
    selectedMovieID: number;
}

/* One morning, Jessica Holland, a Scottish orchid farmer visiting her sister in Bogotá, is woken by a loud ‘bang’. This haunting sound dispels her sleep for days, calling into question her identity and guiding her from recording studios to secluded jungle villages in an attempt to find its source. */

export const Info_window = ({ className, selectedMovieID }: Info_windowProps) => {
    const [movieDescription, setMovieDescription] = useState<string>('');
    const [isDescriptionLoaded, setIsDescriptionLoaded] = useState<boolean>(false);

    useEffect(() => {
        if (typeof window !== 'undefined') {
          const fetchMovieDescription = async () => {
            if (selectedMovieID && selectedMovieID !== 0) {
              console.log('Fetching movie description for movie ID:', selectedMovieID);
              const response = await fetch(`https://api.themoviedb.org/3/movie/${selectedMovieID}?api_key=87816556a329f30685772bb450222859`);
              const data = await response.json();
              if (typeof data.overview !== 'undefined' && data.overview.length > 2) {
                setMovieDescription(data.overview);
                setIsDescriptionLoaded(true);
              }
            }
          };
    
          fetchMovieDescription();
        }
      }, [selectedMovieID]);

    useEffect(() => {
        console.log('Movie description:', movieDescription);
    }, [movieDescription]);

    console.log('Info_window component re-rendered');


    return (
        <div className='mt-3  lg:w-[42.86%] p-[2px] bg-gradient-to-r from-co2 to-grad rounded-lg justify-between flex-col flex'>
            <div className=' justify-between flex flex-col h-full p-4 bg-co1  rounded-lg'>
                <div>
                    <h1 className='nu bg-gradient-to-r from-co2 to-grad text-black font-bold rounded-lg p-2 pl-4 text-center mb-4 text-lg'>Memoria (2021)</h1>
                    <p className=' text-slate-300'>Apichatpong Weerasethakul</p>
                    <p className='pb-2 italic text-slate-400 text-sm'> Director, Writer</p>
                    {isDescriptionLoaded ? (
                        <p>{movieDescription}</p>
                    ) : (
                        <p>Loading...</p>
                    )}
                </div>
                <div className='mt-4'>
                    <h1 className=' w-14 rounded-t-lg text-center text-black bg-co2'>Cast</h1>
                    <div className=' rounded-lg rounded-tl-none bg-gradient-to-r from-co2 to-grad p-[2px]'>
                        <div className=' overflow-x-scroll overflow-y-hidden nu-in scrollbar-none rounded-lg p-3 bg-slate-700 bg-opacity-50 flex flex-row'>
                            <div className='p-2 mr-2 rounded-lg border-gray-200 border hover:bg-gray-200 transition-all hover:text-black'>placeholder</div>
                            <div className='p-2 mr-2 rounded-lg border-gray-200 border hover:bg-gray-200 transition-all hover:text-black'>placeholder</div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    );
};

ChatGPT suggested a number of conditions that should have forced the window to re-render, but nothing works.

2

Answers


  1. import classNames from 'classnames';
    import React from 'react';
    import { useEffect, useState } from 'react';
    
    export interface Info_windowProps {
      className?: string;
      selectedMovieID: number;
    }
    
    export const Info_window = ({ className, selectedMovieID }: Info_windowProps) => {
      const [movieDescription, setMovieDescription] = useState<string>('');
      const [isDescriptionLoaded, setIsDescriptionLoaded] = useState<boolean>(false);
    
      useEffect(() => {
        if (typeof window !== 'undefined') {
          const fetchMovieDescription = async () => {
            if (selectedMovieID && selectedMovieID !== 0) {
              console.log('Fetching movie description for movie ID:', selectedMovieID);
              const response = await fetch(`https://api.themoviedb.org/3/movie/${selectedMovieID}?api_key=87816556a329f30685772bb450222859`);
              if (!response.ok) {
                console.error('Error fetching movie description:', response.statusText);
                return;
              }
              const data = await response.json();
              if (typeof data.overview !== 'undefined' && data.overview.length > 2) {
                setMovieDescription(data.overview);
                setIsDescriptionLoaded(true);
              }
            }
          };
    
          fetchMovieDescription();
        }
      }, [selectedMovieID]);
    
      useEffect(() => {
        console.log('Movie description:', movieDescription);
      }, [movieDescription]);
    
      console.log('Info_window component re-rendered');
    
      return (
        <div className='mt-3  lg:w-[42.86%] p-[2px] bg-gradient-to-r from-co2 to-grad rounded-lg justify-between flex-col flex'>
          <div className=' justify-between flex flex-col h-full p-4 bg-co1  rounded-lg'>
            <div>
              <h1 className='nu bg-gradient-to-r from-co2 to-grad text-black font-bold rounded-lg p-2 pl-4 text-center mb-4 text-lg'>Memoria (2021)</h1>
              <p className=' text-slate-300'>Apichatpong Weerasethakul</p>
              <p className='pb-2 italic text-slate-400 text-sm'> Director, Writer</p>
              {isDescriptionLoaded ? (
                <p>{movieDescription}</p>
              ) : (
                <p>Loading...</p>
              )}
            </div>
            <div className='mt-4'>
              <h1 className=' w-14 rounded-t-lg text-center text-black bg-co2'>Cast</h1>
              <div className=' rounded-lg rounded-tl-none bg-gradient-to-r from-co2 to-grad p-[2px]'>
                <div className=' overflow-x-scroll overflow-y-hidden nu-in scrollbar-none rounded-lg p-3 bg-slate-700 bg-opacity-50 flex flex-row'>
                  <div className='p-2 mr-2 rounded-lg border-gray-200 border hover:bg-gray-200 transition-all hover:text-black'>placeholder</div>
                  <div className='p-2 mr-2 rounded-lg border-gray-200 border hover:bg-gray-200 transition-all hover:text-black'>placeholder</div>
                </div>
              </div>
            </div>
          </div>
        </div>
      );
    };
    

    To address probable issues, an error check was included after the retrieve call. The execution ends early and an error is noted if the response status is not between 200 and 299, as this indicates a problem.
    Using console.error, which is suited for logging errors, the error message is recorded.
    The fetchMovieDescription method was not enclosed in the useEffect hook in the code sample you provided, which may have been an oversight. To make sure the method is executed when the selectedMovieID changes, I added the necessary useEffect hook.

    The movieDescription is recorded by the second useEffect hook whenever it changes. For the purpose of debugging, this can be useful.
    The component is re-rendering as anticipated, according to the console.log line outside of the useEffect hooks.

    Login or Signup to reply.
  2. If the console logs confirm that the API is being called correctly and the movieDescription state is being updated, but the paragraph element is not re-rendering to display the updated value, it could be due to the nature of the movieDescription state update.

    Here are a few possible solutions to ensure that the updated value is rendered in the paragraph element:

    1. Check if the movieDescription state is being set correctly: You can add a console.log() statement inside the setMovieDescription callback to verify that the state is being updated with the new value.
    setMovieDescription(data.overview);
    console.log('Movie description set:', data.overview);
    
    1. Make sure that the isDescriptionLoaded state is being updated to true after setting the movieDescription state. You can add a console.log() statement inside the setIsDescriptionLoaded callback to check if it’s being called.
    setIsDescriptionLoaded(true);
    console.log('isDescriptionLoaded set to true');
    
    1. Ensure that the initial value of isDescriptionLoaded is set to false by default. This ensures that the "Loading…" message is displayed initially before the description is loaded.
    const [isDescriptionLoaded, setIsDescriptionLoaded] = useState<boolean>(false);
    
    1. Double-check the condition in the JSX rendering to ensure that the correct branch is executed based on the isDescriptionLoaded state.
    {isDescriptionLoaded ? (
      <p>{movieDescription}</p>
    ) : (
      <p>Loading...</p>
    )}
    

    If none of these solutions resolve the issue, please provide more information about the specific behavior or any error messages you’re encountering. That will help in further troubleshooting the problem.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search