Inflearn brand logo image

인프런 커뮤니티 질문&답변

hundo1217님의 프로필 이미지
hundo1217

작성한 질문수

따라하며 배우는 리액트 A-Z[19버전 반영]

Styled Component를 이용한 비디오 배너 생성하기

런타임 에러 ㅠㅠ

작성

·

34

0

- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.

import axios from "../api/axios";
import React, { useEffect, useState } from 'react'
import requests from '../api/requests';
import "./Banner.css"
import styled from "styled-components";
export default function Banner() {
    const [movie, setMovie] = useState([]);
    const [isClicked, setIsClicked] = useState(false);

    useEffect(() => {
        fetchData();
    }, []);
    const fetchData = async() => {
        //현재 상영중인 영화 정보를 가져오기 (여러 영화)
        const request = await axios.get(requests.fetchNowPlaying);
        //여러 영화 중 영화 하나의 ID를 가져오기
        const movieId = request.data.results[
          Math.floor(Math.random() * request.data.results.length)
        ].id;

        //특정 영화의 더 상세한 정보를 가져오기 (비디오 정보도 포함)
        const {data: movieDetail} = await axios.get(`movie/${movieId}`, 
          {
            params: {append_to_response: "videos"},
          });
          setMovie(movieDetail);
    }
const truncate = (str, n) => {
  return str?.length > n ? str.substr(0, n - 1) + "..." : str;
}
console.log('movie', movie);
if(!isClicked) {
return (
    <header
    className="banner"
    style={{
      backgroundImage: `url("https://image.tmdb.org/t/p/original/${movie.backdrop_path}")`,
      backgroundPosition: "top center",
      backgroundSize: "cover",
    }}>
      <div className="banner__contents">
        <h1 className="banner__title">
          {movie.title || movie.name || movie.original_name} 
          </h1>
          <div className="banner__buttons">
            <button 
            className="banner__button play" 
            onClick={() => setIsClicked(true)}
            >
              Play</button>
            <button className="banner__button info">More Information</button>

          </div>

          <h1 className="banner_description"> {truncate(movie.overview, 100)}
        </h1>
      </div>
      <div className="banner--fadeBottom"></div>
    </header>
  );
} else{
  return (
    <Container>
      <HomeContainer>
        <Iframe 
        width="640"
        height="360" 
        src={`https://www.youtube.com/embed/${movie.videos.results[0].key}?controls=0&autoplay=1&loop=1&mute=1&playlist=${movie.videos.results[0].key}`}
        title="YouTube video player" 
        allow="autoplay; fullscreen" 
        ></Iframe>
      </HomeContainer>
    </Container>
  );
}
}

const Iframe = styled.iframe`
width: 100%;
height: 100%;
opacity: 0.65;
border: none;

&::after {
content:"";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}`
const Container = styled.div`
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 100%;
height: 100vh;
`

const HomeContainer = styled.div`
width: 100vw;
height: 100vh;`
image.png

 

답변 1

0

안녕하세요, 인프런 AI 인턴입니다.

제공해주신 코드와 오류 메시지를 바탕으로 분석해보겠습니다. 발생한 오류는 TypeError: Cannot read properties of undefined (reading 'key')로, 이는 보통 movie.videos.results 배열에 접근하려 할 때 null 또는 undefined인 경우 발생하는 문제입니다.

해결방법과 관련 링크

  1. 초기 데이터 로딩 체크:
    useState로 초기 상태를 빈 배열이나 빈 객체로 설정하는 대신 null을 고려할 수 있습니다. 이는 데이터가 아직 로딩되지 않았을 때의 null 상태를 명확히 해줍니다.

  2. 데이터 존재 여부 확인:
    movie.videos 또는 movie.videos.results가 존재하는지 확인하여, 존재하는 경우에만 key에 접근하도록 코드를 작성해야 합니다.

   if (movie.videos && movie.videos.results && movie.videos.results.length) {
       const videoKey = movie.videos.results[0].key;
       // ... your code
   }
  1. 옵셔널 체이닝 사용:
    옵셔널 체이닝을 사용하여 안전하게 데이터를 접근할 수 있습니다.
   src={`https://www.youtube.com/embed/${movie.videos?.results?.[0]?.key}?controls=0&autoplay=1&loop=1&mute=1&playlist=${movie.videos?.results?.[0]?.key}`}

관련된 유사한 기존 질문과 답변을 참고해 주시면 도움이 될 것입니다:

이러한 방법을 통해 코드를 수정하면 오류를 해결할 수 있을 것입니다. 추가적으로 문제 발생 시, React의 개발자 도구를 이용하여 상태 변화 및 데이터 흐름을 모니터링해주세요.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

hundo1217님의 프로필 이미지
hundo1217

작성한 질문수

질문하기