[React] YouTube Clone week1

semi·2021년 7월 25일
1

CloneCoding

목록 보기
1/4
post-thumbnail

목표

메인화면(홈화면) html&css
2) 영상시청화면 html&css
3) 영상화면의 댓글입력 기능
메뉴 눌렀을 때 메뉴바
5) 로그인창 및 로그인 기능


1. 메인화면(홈화면)


메인화면은 아래와 같이 크게 3block으로 나누었다.

React를 사용하여 구현하였으며 block들을 각각 모듈로 나누어서 구현하였다.

먼저, 모든 모듈을 담고있는 App.js는 다음과 같다.
(모든 모듈을 담고있다는 표현은 정확하지 않은것 같다. 정확한 표현을 찾아보는 것이 필요할듯)

App.js

import React from 'react';
import SearchBar from './SearchBar';
import VideoBody from './VideoBody';
import MenuBar from './MenuBar';
let menuState = true;
function App() {
  return (
    <>
      <div className='searchbar'>
        <SearchBar menuState={menuState} />
      </div>

      <div style={{ display: 'flex', flexDirection: 'row' }}>
        {menuState === true && (
          <div className='menubar'>
            <MenuBar />
          </div>
        )}
        <div className='videobody'>
          <VideoBody />
        </div>
      </div>
    </>
  );
}

export default App;

이 부분을 진행하면서 아직 동적인 기능이 없기 때문에 특별하게 참고할 사항은 없다.

우선 진행중인 메인화면에서의 동적인 기능은 searchbar의 MenuIcon을 클릭시 menubar가 생성되었다가 없어졌다가 하는 동작을 진행중이다.

let menuState=true;
//...//
<div className='searchbar'>
        <SearchBar menuState={menuState} />
</div>
<div style={{ display: 'flex', flexDirection: 'row' }}>
        {menuState === true && (
          <div className='menubar'>
            <MenuBar />
</div>
)}
</div>

App.js 에서 위 코드부분을 보면
true로 초기화한 menuState라는 변수를 선언하고
이 변수를 props로 SearchBar.js에 넘겨준다.
SearchBar.js에서는 menuIcon에 onClick 이벤트를 추가하여 클릭시 menuState 값이 반전되도록 구현하였다.
다시 App.js에서 를 추가할 때 &&를 사용하여 menuState값이 true이면 가 생성되도록 하고 아니면 생성되지 않도록 구현하였다.
현재 console을 통해 menuIcon 클릭시 menuState값이 변하는 것이 정상적으로 실행되는 것은 확인하였지만 SearchBar.js에서 제어하는 menuState값이 App.js에서는 변하지 않는 것인지 가 생성되고 생성되지 않고 하는 부분은 아직 동작하지 않고 있다.

props란 무엇인가 - 참고

메뉴바 동작하지 않는 부분
-> useState 사용하여 해결 (추가로 정리할 예정)

추가적으로 css부분에서 어려움을 겪었다.
우선 react에서 css를 적용하려면 2가지 방법이 있다.
1. css 파일을 추가하는 방법
2. tag에 style={}을 직접 추가하는 방법
첫번째 방식은 기본적으로 아는 방법이지만 여러개의 모듈로 나누어서 진행을 하다보니 다른 모듈에 적용하는 것에 있어서 어려움이 있었다.

직관적으로 css를 확인하고 적용하기 위해서 2번째 방법을 사용하였다.

<div style={{ display: 'flex', flexDirection: 'row' }}>
	{menuState === true && (
	<div className='menubar'>
		<MenuBar />
	</div>
	)}
	<div className='videobody'>
		<VideoBody />
	</div>
</div>

App.js 부분에서 위 코드를 보면 SearchBar 와는 따로 MenuBar와 VideoBody를 묶어놓았다.

SearchBar는 상단에 자기 혼자만 고정으로 위치하고 MenuBar와 VideoBody는 가로정렬로 상단바 아래에 같이 위치해야되기 때문이다.

두 모듈을 가로정렬 하기 위해 하나의 div tag로 묶고

<div style={{ display: 'flex', flexDirection: 'row' }}>

style로 display는 flex로 flexDirection은 row로 설정해주었다.

display를 flex로 설정하여 두 태그를 감싼 div 태그가 부모 속성인 flex container가 된다.
이렇게 설정하면 MenuBar와 VideoBody가 flex container의 자식 속성 flex item이 된다.

부모 속성에서 flexDirection을 설정하면 자식속성들을 정렬할 수 있다.
flexDirection에서 값을 row로 설정하면 가로정렬 column으로 설정하면 세로정렬이다.

flexbox란? 참고


Searchbar.js


다음으로 상단바 부분이다.

import React from 'react';
import LogoImg from './logo.jpg';
import MenuImg from './menuImg.jpg';

const barStyle = {
  color: 'black',
  background: 'white',
  padding: '10px',
  fontSize: '20px',
  border: '1px solid gainsboro',
  lineHeight: 1.5,
  display: 'flex', 
  flexDirection: 'row',
};

function SearchBar({ menuState }) {
  function onClickMenuBtn() {
    menuState = !menuState;
    console.log(menuState);
  }

  return (
    <>
      <div style={barStyle}>
        <div onClick={onClickMenuBtn}>
          <img src={MenuImg} width='45' height='45' alt='menuIcon' />
        </div>
        <div>
          <img src={LogoImg} width='150' height='45' alt='logoImg' />
        </div>
        <div>
          <input
            type='text'
            placeholder='검색'
            style={{ width: '300px', height: '45px' }}
          ></input>
        </div>
        <div>
          <button style={{ width: '45px', height: '45px' }}>🔍</button>
        </div>
      </div>
    </>
  );
}

export default SearchBar;

앞서 언급한 menuIcon의 클릭 이벤트는 위 코드의 다음 부분을 참고하면 된다.

//...//
function SearchBar({ menuState }) {
  function onClickMenuBtn() {
    menuState = !menuState;
    console.log(menuState);
  }
  return (
    <>
      <div style={barStyle}>
        <div onClick={onClickMenuBtn}>
          <img src={MenuImg} width='45' height='45' alt='menuIcon' />
        </div>
//...//

이미지추가 참고


VideoBody.js

import React from 'react';
import VideoList from './VideoList';
const bodyStyle = {
  position: 'absolute',
  color: 'black',
  background: 'white',
  width: '100%',
  display: 'flex', 
  flexDirection: 'column',
};
function VideoBody() {
  return (
    <div style={bodyStyle}>
      <VideoList />
      <VideoList />
      <VideoList />
    </div>
  );
}

export default VideoBody;

VideoList.js

import React from 'react';

function VideoList() {
  return (
    <div style={{ display: 'flex', flexDirection: 'row' }}>
      <div style={{ border: '0.5px solid gainsboro', height: '35%' }}>
        <video></video>
        <div>영상제목1</div>
        <div>채널명</div>
      </div>
      <div style={{ border: '0.5px solid gainsboro', height: '35%' }}>
        <video></video>
        <div>영상제목2</div>
        <div>채널명</div>
      </div>
      <div style={{ border: '0.5px solid gainsboro', height: '35%' }}>
        <video></video>
        <div>영상제목3</div>
        <div>채널명</div>
      </div>
      <div style={{ border: '0.5px solid gainsboro', height: '35%' }}>
        <video></video>
        <div>영상제목4</div>
        <div>채널명</div>
      </div>
    </div>
  );
}

export default VideoList;

import React from 'react';
const barStyle = {
  color: 'black',
  background: 'white',
  fontSize: '20px',
  lineHeight: 3,
  width: '200px',
  border: '0.5px solid gainsboro',
};
function MenuBar() {
  return (
    <div style={barStyle}>
      <div>
        <div></div>
        <div>탐색</div>
        <div>구독</div>
      </div>
      <div>
        <div>구독 목록</div>
      </div>
      <div>
        <div>설정</div>
        <div>고객센터</div>
      </div>
    </div>
  );
}
export default MenuBar;

0개의 댓글