Nextjs와 Tailwindcss로 Youtube 클론을 만들어 봅시다 🎉(3부)

마지막 두 섹션에서는 YouTube 클론의 정적 섹션을 빌드했습니다. 이 섹션에서는 웹 페이지의 콘텐츠에 대한 데이터를 가져옵니다. 이를 위해 index.js 파일에 다음과 같은 serverSideProp을 생성해 보겠습니다.

export async function getServerSideProps(context){
  const query = context.query.query;
  const header = {
        'X-RapidAPI-Key': process.env.NEXT_APP_API_KEY,
        'X-RapidAPI-Host': RapidAPI-Host
      }
{/* If the user submitted something from the input field, then fetch for that keyword else fetch for trending videos */}
  if (query){
    const options = {
      method: 'GET',
      url: 'https://youtube-search-and-download.p.rapidapi.com/search',
      params: {
        query: query,
        hl: 'en',
        type: 'v'
      },
      headers:header
      };
      const response = await axios.request(options);

      return {
        props: {
          data: response.data.contents
        }
      }
  }else{
    const options = {
    method: 'GET',
    url: 'https://youtube-search-and-download.p.rapidapi.com/trending',
    params: { hl: 'en'},
    headers:header
    };
    const response = await axios.request(options);

    return {
      props: {
        data: response.data.contents
      }
    }

  }
}


이제 데이터에 액세스하기 위해 해야 할 일은 다음과 같습니다.

export default function Home({data}){
}


데이터를 본문 구성 요소에 전달합니다.

<Body data={data} /> 


올바르게 기억한다면 Body.js 파일은 다음과 같이 생겼습니다.

function Body({data}) {
  return (
    <div className="col-span-6 relative min-h-screen z-0 ml-4 lg:ml-20">
        <VideoPlayer data={data} />      
    </div>
  )
}


이제 VideoPlayer.js 구성 요소가 중요한 부분입니다.
먼저 다음과 같은 필요한 모든 종속성을 가져옵니다.

import {BsDot, BsThreeDots} from 'react-icons/bs'
import ReactPlayer from 'react-player/lazy'
import Skeleton from 'react-loading-skeleton'
import 'react-loading-skeleton/dist/skeleton.css'


그런 다음 쿼리에서 얻은 데이터로 구성 요소를 빌드합니다.


function VideoPlayer({data}) {
// Set loading feature
  const [loading, setloading] = useState(false)
  useEffect(() =>{
    setTimeout(() => {
      setloading(true)
    }, 2000)
  }, [])

  return (
    <div className='flex flex-wrap gap-5 items-center justify-center my-10'>
      {data && data.map((item, index) => {
        return (      
          <div className='flex flex-col items-center ml-10 md:ml-0' key={index}>

          <div className='relative '>
            {loading ? (
              <>
                <ReactPlayer url={`https://www.youtube.com/watch?v=${item? item.video.videoId: 'Ux_LFXpOrd4'}`} light  height={220} width={380}/>
                <span className='absolute bottom-2 right-3 bg-black text-white p-0.5'>{item.video.lengthText}</span>  
              </>
            ) : <Skeleton height={220} width={380} />} 
          </div>

          <div className='flex mt-4 ml-1'>
{/* Note that for better image rendering, you can use the Image component from next/image */}
            <img src='/youtube.jpg' alt='channel-logo' className='rounded-full mr-3 w-10 h-10 object-cover'/>

            <div>
              <div className='flex justify-between w-80 mb-1'>
                <div><h2 className='text-xl font-bold'>{item? item.video.title.length > 45? `${item.video.title.slice(0,45)}...`:item.video.title:<Skeleton />}</h2></div>
                <div className='rounded-full h-10 w-10 text-center flex items-center justify-center transition-all hover:bg-gray-100'><BsThreeDots size={20} className='rotate-90'/></div>
              </div>
              <div className='opacity-60 font-semibold'>
                {loading? item.video.channelName: <Skeleton />}
              </div>
              <div className='flex opacity-60 font-semibold'>
                <p className='flex items-center justify-center text-center'>{loading ? item.video.viewCountText : <Skeleton />} {' '} {loading? <BsDot />: <Skeleton />}</p>
                <p>{loading? item.video.publishedTimeText: <Skeleton />}</p>
              </div>
            </div>
          </div>
        </div>
        )
      })}

    </div>
  )
}


그러나 검색 기능을 만들려면 header.js 파일을 다음과 같이 수정해야 합니다.
상태 입력을 제어하려면 상태를 선언하십시오.

const [InputValue, setInputValue] = useState('');


그리고 입력 필드에서:

<input type='text' placeholder='Search'
    value={InputValue}
    onChange={(e) =>{
    setInputValue(e.target.value)
}}
onKeyDown={(e) =>{
    if (e.key === 'Enter'){
    router.push(`/?query=${InputValue.toLowerCase()}`);
}}}


그게 다야! YouTube 클론을 만들었습니다. 즐거운 코딩하세요!

좋은 웹페이지 즐겨찾기