본문 바로가기
Tutorial/youtube

05. 나만의 유튜브 사이트 만들기 : 페이지 만들기

by @webstoryboy 2023. 8. 30.
Tutorial/Portfolio

나만의 유튜브 사이트 만들기

by @webs 2023. 09. 01.
05
나만의 유튜브 사이트 만들기 : 페이지 만들기
난이도 중간

소개

안녕하세요! 웹스토리보이입니다. 이 강의는 React 프레임워크와 YouTube API를 이용하여 자신만의 간단한 영상 사이트를 만들어보겠습니다. React의 기본 개념을 이해하고, 컴포넌트를 구조화하고 상태를 관리하는 방법을 학습하게 될 것입니다. 또한 YouTube Data API를 활용하여 외부 데이터를 가져오는 방법을 익히고, API 응답을 처리하여 사용자에게 의미 있는 정보를 제공하는 방법을 이해하게 됩니다. 이로써 자신만의 유튜브 사이트를 만들고, 활용해보는 것을 목표로 합니다. 그럼 한번 시작해볼까요? 🥳

인덱스

  • 1. 셋팅하기
    • 1_1. Node.js 설치
    • 1_2. Vscode 설치
    • 1_3. React.js 설치
  • 2. 라이브러리 설치하기
    • 2_1. 폴더 정리하기
    • 2_2. 라이브러리 설치하기
  • 3. Git 연동하기
    • 3_1. 저장소 만들기
    • 3_2. 모든 파일 올리기
    • 3_3. 깃 상태 확인하기
  • 4. SCSS 셋팅하기
    • 4_1. SCSS 설정하기
    • 4_2. style.scss 설정하기
    • 4_3. fonts.scss 설정하기
    • 4_4. vars.scss 설정하기
    • 4_5. reset.scss 설정하기
    • 4_6. mixin.scss 설정하기
    • 4_7. common.scss 설정하기
  • 5. 페이지 만들기
    • 5_1. 페이지 만들기
    • 5_2. 페이지 컴퍼넌트 만들기

5. 페이지 만들기

5_1. 페이지 만들기

이번에는 페이지를 만들겠습니다. 사실 리액트는 SPA(싱글 페이지)로 되어 있기 때문에 페이지가 존재하지 않습니다. 그래서 가상의 페이지와 주소를 만들어서 작업합니다. 그럼 디테일하게 알아보겠습니다.

SPA(단일 페이지 애플리케이션)는 전통적인 웹 애플리케이션과는 다르게, 페이지 전환 없이 동적으로 콘텐츠를 업데이트하여 사용자 경험을 향상시키는 웹 애플리케이션 형태를 말합니다.

리액트 SPA는 이 두 가지 개념을 결합한 것으로, 리액트를 사용하여 단일 페이지 애플리케이션을 개발하는 것을 의미합니다. 리액트는 가상 DOM (Virtual DOM) 기술을 통해 효율적으로 UI를 관리하고 업데이트합니다. 이는 사용자가 상호 작용하는 동안 필요한 부분만 업데이트하여 전체 페이지를 다시 렌더링하지 않고도 부드러운 경험을 제공합니다.

  • 가상 DOM: 리액트는 가상 DOM을 사용하여 실제 DOM과 상호 작용하며, UI 변경 사항을 미리 계산한 다음 효율적으로 업데이트합니다. 이로 인해 성능 향상을 이룰 수 있습니다.
  • 컴포넌트 기반 아키텍처: 리액트 애플리케이션은 작은 컴포넌트로 구성됩니다. 각 컴포넌트는 자체적으로 상태(state)와 속성(props)을 가질 수 있으며, 이러한 컴포넌트들이 조합되어 전체 UI를 형성합니다.
  • 라우팅: 리액트 SPA에서는 일반적으로 브라우저의 URL을 사용하여 다른 뷰나 페이지 간에 전환할 수 있습니다. 이를 위해 리액트 라우팅 라이브러리를 사용하거나, React Router와 같은 도구를 활용합니다.
  • 비동기 데이터 로딩: SPA는 사용자 경험을 개선하기 위해 비동기적으로 데이터를 로드하고 UI를 업데이트할 수 있습니다. 리액트는 이를 위해 axios, fetch와 같은 API 호출을 지원하며, 상태 관리 라이브러리인 Redux나 MobX와 함께 사용할 수도 있습니다.
  • 상태 관리: 복잡한 SPA에서는 여러 컴포넌트 간에 상태를 효율적으로 관리해야 합니다. 리액트에서는 컴포넌트 내부 상태뿐만 아니라, 전역 상태를 관리하기 위해 Redux, MobX와 같은 상태 관리 라이브러리를 사용할 수 있습니다.
  • Webpack 등 빌드 도구와의 통합: 리액트 프로젝트는 보통 Babel, Webpack과 같은 도구를 사용하여 번들링하고 최적화합니다. 이를 통해 코드의 크기를 줄이고 성능을 향상시킬 수 있습니다.

DOM (Document Object Model)과 Virtual DOM에 대해서 알아보겠습니다.

DOM (Document Object Model)
  • DOM은 웹 페이지의 구조를 표현하는 트리 구조입니다. HTML, XML, 또는 다른 마크업 언어로 작성된 문서를 구조적으로 표현합니다.
  • DOM은 웹 페이지의 모든 요소와 요소 간의 관계를 표현합니다. 각 HTML 요소(태그), 속성, 텍스트 내용 등이 DOM의 노드로 표현됩니다.
  • 실제 DOM은 웹 브라우저의 메모리에 생성되고 관리됩니다. 이는 웹 페이지의 현재 상태를 표현하는 데 사용되며, JavaScript를 통해 동적으로 조작할 수 있습니다.
  • DOM은 브라우저의 성능과 관련하여 주요한 역할을 합니다. DOM 조작은 비용이 높을 수 있으며, 변경 사항을 즉시 실제 DOM에 반영하는 것은 효율적이지 않을 수 있습니다.
Virtual DOM
  • Virtual DOM은 메모리에 존재하는 실제 DOM의 가상 표현입니다. 즉, 가상 DOM은 실제 DOM의 복제입니다.
  • React와 같은 라이브러리 및 프레임워크에서 Virtual DOM을 사용하여 성능을 최적화합니다. 가상 DOM을 사용하여 UI 업데이트를 관리하며, 변경 사항을 효율적으로 처리합니다.
  • Virtual DOM은 업데이트 비용을 최소화하고 성능을 향상시킵니다. 가상 DOM을 사용하면 실제 DOM을 직접 조작하는 대신 변경 사항을 비교하고 최소한의 DOM 조작만을 수행하여 업데이트를 효율적으로 처리합니다.
  • React와 같은 라이브러리와 프레임워크에서 Virtual DOM을 사용하여 UI 업데이트를 관리하고 성능을 최적화하는 데 활용됩니다.

리액트 SPA는 사용자 인터페이스를 개선하고 웹 애플리케이션의 성능을 향상시키기 위해 리액트를 사용하여 구축한 단일 페이지 애플리케이션입니다. 이러한 SPA 접근 방식은 사용자 경험을 향상시키고, 웹 애플리케이션의 성능과 유지 관리성을 향상시키는 데 도움이 됩니다. 그렇기 때문에 가상의 페이지를 만들기 위해서 초반에 react-router-dom을 설치한 적이 있습니다. 이것을 통해 가상의 주소를 만들어 보겠습니다.

App.js 파일을 다음과 같이 작성합니다. 가상의 주소를 만들면 컨텐츠를 불러와야 합니다. 컨텐츠는 컴퍼넌트를 통해 불러옵니다. 저는 총 12개의 페이지를 제작할 것입니다.

import React from 'react'
import { BrowserRouter, Routes, Route } from 'react-router-dom';

import Home from './pages/Home'
import Today from './pages/Today'
import Developer from './pages/Developer'
import Webd from './pages/Webd'
import Website from './pages/Website'
import Gsap from './pages/Gsap'
import Port from './pages/Port'
import Youtube from './pages/Youtube'
import Channel from './pages/Channel'
import Video from './pages/Video'
import Search from './pages/Search'
import Not from './pages/Not'

const App = () => {
    return (
        <BrowserRouter>
            <Routes>
                <Route path='/' element={<Home />} />
                <Route path='/today' element={<Today />} />
                <Route path='/developer' element={<Developer />} />
                <Route path='/webd' element={<Webd />} />
                <Route path='/website' element={<Website />} />
                <Route path='/gsap' element={<Gsap />} />
                <Route path='/port' element={<Port />} />
                <Route path='/youtube' element={<Youtube />} />
                <Route path='/channel/:channelId' element={<Channel />} />
                <Route path='/video/:videoId' element={<Video />} />
                <Route path='/search/:searchId' element={<Search />} />
                <Route path='*' element={<Not />} />
            </Routes>
        </BrowserRouter>
    );
}

export default App;

React 애플리케이션의 라우팅을 설정하고 관리하기 위해 React Router의 BrowserRouter, Routes, 및 Route 구성 요소를 사용하는 기본 애플리케이션 구조를 정의합니다.

  • import React from 'react'; : 리액트 라이브러리를 불러옵니다.
  • import { BrowserRouter, Routes, Route } from 'react-router-dom'; : React Router에서 BrowserRouter, Routes, Route 컴포넌트를 불러옵니다. 이 컴포넌트들은 브라우저 라우팅을 설정하고 경로별로 컴포넌트를 매핑하는 데 사용됩니다.
  • 라우팅 경로 및 컴포넌트 임포트 : 다양한 뷰 컴포넌트들을 해당 경로에 연결하고, 이를 위해 각 컴포넌트들을 임포트합니다.
  • const App = () => ( : App이라는 이름의 함수형 컴포넌트를 정의합니다. 이 컴포넌트는 라우팅 구성을 담당하고 있습니다.
  • <BrowserRouter> : 리액트 라우터의 BrowserRouter 컴포넌트로 감싸여 있습니다. 이 컴포넌트는 브라우저의 주소 히스토리 API를 사용하여 라우팅을 관리합니다.
  • <Routes> : BrowserRouter 내에서 사용되며, 다양한 경로에 대한 라우트 정보를 정의합니다.
  • <Route path='/' element={<Home />} /> : 경로가 '/'인 경우, Home 컴포넌트를 렌더링합니다. element prop을 사용하여 해당 경로에 대한 컴포넌트를 지정합니다.
  • 나머지 <Route> 컴포넌트도 동일한 방식으로 설정됩니다. 예를 들어, /video/:videoId 경로는 Video 컴포넌트를, /channel/:channelId 경로는 Channel 컴포넌트를, 그리고 /search/:searchId 경로는 Search 컴포넌트를 렌더링합니다. :videoId, :channelId, :searchId는 경로 파라미터를 나타내며, 실제로 해당 변수에 따라 다른 콘텐츠를 렌더링할 수 있습니다.
  • </Routes> : Routes 컴포넌트의 닫는 태그로, 라우트 설정을 마무리합니다.
  • </BrowserRouter> : BrowserRouter 컴포넌트의 닫는 태그로, 라우터 설정을 마무리합니다.
  • export default App; : App 컴포넌트를 외부로 내보냅니다. 이는 애플리케이션의 진입점이 됩니다.

5_2. 페이지 컴퍼넌트 만들기

페이지를 구성했다면 그 페이지에 보여줄 컴퍼넌트를 만들어 보겠습니다.

리액트 컴포넌트는 리액트 애플리케이션의 구성 요소로, UI를 작은 단위로 분리하여 재사용 가능하고 모듈화된 코드로 관리할 수 있도록 도와주는 개념입니다. 컴포넌트는 화면의 여러 부분을 독립적으로 생성하고 관리할 수 있도록 해주며, 각각의 컴포넌트는 자체적인 상태(state)와 속성(props)을 가질 수 있습니다.

  • 클래스 컴포넌트 (Class Components): ES6 클래스를 확장하여 만든 컴포넌트입니다. 클래스 컴포넌트는 라이프사이클 메서드를 사용할 수 있어서 컴포넌트의 생명 주기 동안 다양한 동작을 처리할 수 있습니다. 클래스 컴포넌트는 주로 상태 관리와 라이프사이클 이벤트 처리를 위해 사용됩니다.
  • 함수형 컴포넌트 (Functional Components): 함수로 작성된 컴포넌트로, 리액트의 최신 기능을 활용하여 간결하게 컴포넌트를 작성할 수 있습니다. 함수형 컴포넌트는 상태와 라이프사이클 메서드를 사용할 수 없었던 기존의 함수 컴포넌트와 달리, React Hooks를 통해 상태 관리와 라이프사이클 이벤트 처리를 할 수 있게 되었습니다.

JSX는 JavaScript XML의 약자로, 리액트에서 UI를 작성하기 위한 문법 확장입니다. JSX를 사용하면 JavaScript 코드 내부에서 HTML과 유사한 구문으로 UI 요소를 작성할 수 있어, 가독성을 높이고 개발자들이 리액트 컴포넌트를 작성하기 쉬워집니다.

폴더 정리는 다음과 같이 하겠습니다. view 폴더를 만들과 다음과 같이 jsx 페이지를 만들겠습니다.

  • src
    • assets
    • pages
      • Channel.jsx
      • Developer.jsx
      • Gsap.jsx
      • Home.jsx
      • Not.jsx
      • Port.jsx
      • Search.jsx
      • Today.jsx
      • Video.jsx
      • Webd.jsx
      • Website.jsx
      • Youtube.jsx
    • App.js
    • index.js

각 페이지는 다음과 같이 작업합니다.

import React from 'react'

const Channel = () => {
    return (
        <div>Channel</div>
    )
}
    
export default Channel
import React from 'react'

const Developer = () => {
    return (
        <div>Developer</div>
    )
}

export default Developer
import React from 'react'

const Gsap = () => {
    return (
        <div>Gsap</div>
    )
}

export default Gsap
import React from 'react'

const Home = () => {
    return (
        <div>Home</div>
    )
}

export default Home
import React from 'react'

const Not = () => {
    return (
        <div>Not</div>
    )
}
    
export default Not
import React from 'react'

const Port = () => {
    return (
        <div>Port</div>
    )
}
    
export default Port
import React from 'react'

const Search = () => {
    return (
        <div>Search</div>
    )
}
    
export default Search
import React from 'react'

const Today = () => {
    return (
        <div>Today</div>
    )
}
    
export default Today
import React from 'react'

const Video = () => {
    return (
        <div>Video</div>
    )
}
    
export default Video
import React from 'react'

const Webd = () => {
    return (
        <div>Webd</div>
    )
}
    
export default Webd
import React from 'react'

const Website = () => {
    return (
        <div>Website</div>
    )
}
    
export default Website
import React from 'react'

const Youtube = () => {
    return (
        <div>Youtube</div>
    )
}
    
export default Youtube

여기까지 잘 따라 했다면 터미널을 통해 npm start 라고 작성합니다. 브라우저가 열리고 Home라고 나타나면 성공한 것입니다. 주소창에 /gsap를 치면 gsap 텍스트가 나타납니다. 주소창에 /webd를 치면 webd 텍스트가 나타납니다. 주소창에 /search/랜덤알파벳을 치면 Search가 나타납니다. 이렇게 하면 페이지가 다 만들어 진것입니다. 만약에 /webdd와 같이 없는 주소를 넣으면 Not이라는 텍스트가 나타나야 합니다. /search도 마찬가지로 뒤에 아이디와 같은 텍스트가 없다면 없는 페이지로 이동합니다.

이렇게 나오면 성공한 것입니다.

youtube2023

마무리

git 올리기

터미널에서 다음과 같이 작성하겠습니다. 새로운 페이지가 올라오는 것을 확인 할 수 있습니다.

webstoryboyhwang@Webstoryboyui-MacBookPro webs-youtube % git add .
webstoryboyhwang@Webstoryboyui-MacBookPro webs-youtube % git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
    (use "git restore --staged ..." to unstage)
        modified:   src/App.js
        new file:   src/pages/Channel.jsx
        new file:   src/pages/Developer.jsx
        new file:   src/pages/Gsap.jsx
        new file:   src/pages/Home.jsx
        new file:   src/pages/Not.jsx
        new file:   src/pages/Port.jsx
        new file:   src/pages/Search.jsx
        new file:   src/pages/Today.jsx
        new file:   src/pages/Video.jsx
        new file:   src/pages/Webd.jsx
        new file:   src/pages/Website.jsx
        new file:   src/pages/Youtube.jsx

webstoryboyhwang@Webstoryboyui-MacBookPro webs-youtube % git commit -m "페이지 완성"
[main c2d2a3e] 페이지 완성
    13 files changed, 140 insertions(+), 3 deletions(-)
    create mode 100644 src/pages/Channel.jsx
    create mode 100644 src/pages/Developer.jsx
    create mode 100644 src/pages/Gsap.jsx
    create mode 100644 src/pages/Home.jsx
    create mode 100644 src/pages/Not.jsx
    create mode 100644 src/pages/Port.jsx
    create mode 100644 src/pages/Search.jsx
    create mode 100644 src/pages/Today.jsx
    create mode 100644 src/pages/Video.jsx
    create mode 100644 src/pages/Webd.jsx
    create mode 100644 src/pages/Website.jsx
    create mode 100644 src/pages/Youtube.jsx
webstoryboyhwang@Webstoryboyui-MacBookPro webs-youtube % git push -u origin main
Enumerating objects: 20, done.
Counting objects: 100% (20/20), done.
Delta compression using up to 10 threads
Compressing objects: 100% (17/17), done.
Writing objects: 100% (17/17), 2.35 KiB | 2.35 MiB/s, done.
Total 17 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/webstoryboy/webs-youtube.git
    7eaa67f..c2d2a3e  main -> main
branch 'main' set up to track 'origin/main'.

리액트에서 가상의 페이지를 만들어 봤습니다. 실제 페이지가 아닌 가상의 주소를 만들었습니다. 리액트는 기본적인 구조가 Virtual DOM이기 때문에 이런 현상이 생기는거 이제는 이해가 가시죠? 오늘도 수고하셨습니다. 🥹


예제 목록

댓글