클론코딩 하나 해놓고 웹사이트를 만들겠다던 과거의 나 ,, 미쳤었다! ^^
하다보니 너무 부족한 것을 깨닫고 클론코딩 하나를 더 할 것이다
이 분 강의가 설명도 잘 되어있고 많은 수강생들이 있어 오류 찾기도 수월했다
[무료] 따라하며 배우는 노드, 리액트 시리즈 - 유튜브 사이트 만들기 - 인프런 | 강의
이 강의를 통해 리액트와 노드의 개념을 익히는 것뿐만이 아닌 실질적으로 어떻게 웹사이트를 만들 수 있는지를 배울 수 있습니다., - 강의 소개 | 인프런...
www.inflearn.com
기초적인 MongoDB 연결, boilerplate 다운은 끝냈으므로 비디오 업로드 FORM 만들기부터 할 것이다!
1. Upload Page 만들기
비디오 업로드 폼을 만들 것이므로 views 폴더 안에 VideoUploadPage라는 폴더를 하나 생성한다
그리고 그 안에 VideoUploadPage.js파일도 생성한다
js 파일에 functional component로 작성해줄 것이다
React에서 함수형 컴포넌트와 클래스형 컴포넌트가 있는데,
함수형 컴포넌트는 props 객체 인자를 받은후 반환하는 특징이 있어 '함수형' 컴포넌트이고,
클래스형 컴포넌트는 state 기능, life cycle 기능을 사용할 수 있으며 임의의 메서드를 정의할 수 있다. render 함수가 꼭 있어야 하고 그 안에 JSX를 반환한다
요즘은 함수형 컴포넌트와 훅을 같이 이용하는 추세라고 한다~
클래스형 컴포넌트보다 선언하기 편하고, 메모리 자원을 덜 사용하기 때문이다!
쨌든 강의에서는 함수형 컴포넌트를 쓴다
VideoUploadPage.js의 기본 틀을 작성해준다
import React from "react";
function VideoUploadPage(){
return (
<div>VideoUploadPage</div>
)
}
export default VideoUploadPage // 외부에서 쓸 수 있게 export
(rfce 단축키 이용 가능)
2. Upload Page Route 만들기
App.js로 가서 방금 만든 VideoUploadPage를 연결해줘야 한다
import VideoUploadPage from './views/VideoUploadPage/VideoUploadPage';
Route도 해준다
<Route exact path="/video/upload" component={Auth(VideoUploadPage, true)} />
Auth에서 null, false, true가 있는데 의미가 각각 다르다
null : 아무나 접속 가능
false : 로그인 하면 못 들어감
true : 로그인 한 사람만 들어감
route 설정을 하고 http://localhost:3000/video/upload 로 접속하면
로그인 안 했을 때는 로그인 창이 뜨고,
로그인 했을 때는
이렇게 뜬다
3. Upload Page Header Tab 만들기
페이지 상단 오른쪽에 video/upload로 가는 메뉴를 만들 것이다
아래의 순서로 이동해준다
로그인 한 사람과 로그인 하지 않은 사람들의 화면이 다르다
if (user.userData && !user.userData.isAuth) {
return ( // 로그인 안 한 사람
<Menu mode={props.mode}>
<Menu.Item key="mail">
<a href="/login">Signin</a>
</Menu.Item>
<Menu.Item key="app">
<a href="/register">Signup</a>
</Menu.Item>
</Menu>
)
} else { // 로그인한 사람
return (
<Menu mode={props.mode}>
<Menu.Item key="logout">
<a onClick={logoutHandler}>Logout</a>
</Menu.Item>
</Menu>
)
}
비디오 업로드는 로그인한 사람만 가능하므로 else 구문에 아래의 코드를 넣어준다
<Menu.Item key="upload">
<a href="/video/upload">Video</a>
</Menu.Item>
그러고 나서 localhost:3000으로 들어가보면
오른쪽 상단에 있는 Video를 클릭하면
4. Form Template 만들기
단순한 작업이므로 설명 없이 코드만 올리겠음
<VideoUploadPage.js>
import React from "react";
import {Typography, Button, Form, message, Input, Icon} from 'antd';
const { Title } = Typography;
const { TextArea } = Input;
function VideoUploadPage(){
return (
<div style={{maxWidth : '700px', margin:'2rem auto'}}>
<div style={{textAlign: 'center', marginBottom:'2rem'}}>
<Title level={2}>Upload Video</Title>
</div>
<Form onSubmit>
<div style={{display:'flex', justifyContent:'space-between'}}>
{/*Drop Zone*/}
{/*Thumbnail*/}
<div>
<img src alt />
</div>
</div>
<br/>
<br/>
<label>Title</label>
<Input onChange value />
<br/>
<br/>
<label>Descriptions</label>
<TextArea
onChange
value
/>
<br/>
<br/>
<select onChange>
<option key value></option>
</select>
<br/>
<br/>
<select onChange>
<option key value></option>
</select>
<br/>
<br/>
<Button type="primary" size="large" onClick>
Submit
</Button>
</Form>
</div>
)
}
export default VideoUploadPage // 외부에서 쓸 수 있게
이렇게 만든 틀은
이렇게 생겼다
5. Drop-zone 다운받기
파일을 올리는 템플릿을 만들기 위해 drop-zone 다운로드가 필요하다
Dropzone.js는 대표적인 파일 업로드 라이브러리다
client에서 다운받을 것이다
cd client
npm install react-dropzone --save
다운받고 나서 다시 npm run dev로 창을 열고
VideoUploadPage.js을 또 수정한다
import React from "react";
import {Typography, Button, Form, message, Input, Icon} from 'antd';
import Dropzone from "react-dropzone";
const { Title } = Typography;
const { TextArea } = Input;
function VideoUploadPage(){
return (
<div style={{maxWidth : '700px', margin:'2rem auto'}}>
<div style={{textAlign: 'center', marginBottom:'2rem'}}>
<Title level={2}>Upload Video</Title>
</div>
<Form onSubmit>
<div style={{display:'flex', justifyContent:'space-between'}}>
// 새로 수정한 부분
{/*Drop Zone*/}
<Dropzone
onDrop
multiple
maxSize>
{({getRootProps, getInputProps}) => (
<div style={{ width: '300px', height: '240px', border: '1px solid lightgray',
alignItems: 'center', justifyContent: 'center', display : 'flex'}} {...getRootProps()}>
<Input {...getInputProps()} />
<Icon type="plus" style={{fontSize:'3rem'}}/>
</div>
)}
</Dropzone>
//
{/*Thumbnail*/}
<div>
<img src alt />
</div>
</div>
<br/>
<br/>
<label>Title</label>
<Input onChange value />
<br/>
<br/>
<label>Descriptions</label>
<TextArea
onChange
value
/>
<br/>
<br/>
<select onChange>
<option key value></option>
</select>
<br/>
<br/>
<select onChange>
<option key value></option>
</select>
<br/>
<br/>
<Button type="primary" size="large" onClick>
Submit
</Button>
</Form>
</div>
)
}
export default VideoUploadPage // 외부에서 쓸 수 있게
이러면
완성
// 저 플러스(+) 버튼이 가운데 정렬 되지 않아 display: 'flex' 코드를 추가하였다
6. onChange func 만들기
onDrop, onChange 세팅을 해주지 않으면 아무리 타이핑해도 입력되어지지 않는다
그러므로 이번 시간에는 onChange 세팅을 할 것이다
먼저 두 가지의 select를 보았을 것이다
하나는 영상을 비공개/공개할 것인지, 나머지 하나는 영상의 종류가 무엇인지를 결정하는 select이다
처음꺼는 2개의 선택지, 두번째꺼는 4개의 선택지를 만들 것이다
const PrivateOptions = [
{value : 0, label : "Private"},
{value : 1, label : "Public"}
]
const CategoryOptions = [
{value : 0, label : "Film & Animation"},
{value : 1, label : "Autos & Vehicles"},
{value : 2, label : "Music"},
{value : 3, label : "Pets & Animals"},
]
그리고 state 함수를 써줄 것이다
state 안에 value를 저장한다
const [VideoTitle, setVideoTitle] = useState("")
const [Description, setDescription] = useState("")
const [Private, setPrviate] = useState(0)
const [Category, setCategory] = useState("Film & Animation")
기본세팅은 빈 문자열 / 빈 문자열 / 0(private) / 0(Film & Animation) 순이다
입력받는 곳이 Title, Descriptions, private/public 선택, category 선택 총 4곳이었으므로 useState 4개를 작성한 것이다
먼저 Title
<label>Title</label>
<Input
onChange={onTitleChange}
value={VideoTitle}
/>
Descriptions
<label>Descriptions</label>
<TextArea
onChange={onDescriptionChange}
value = {Description}
/>
Private/Public
<select onChange={onPrivateChange}>
{PrivateOptions.map((item, index) => (
<option key={index} value={item.value}>{item.label}</option>
))}
</select>
Category
<select onChange={onCategoryChange}>
{CategoryOptions.map((item, index) => (
<option key={index} value={item.value}>{item.label}</option>
))}
</select>
// 참고로 option 쓸 때 key값을 정해주지 않으면 오류가 난다고 한다
onXXXXChange형식으로 다 만들어줬다
그럼 함수 작성을 해보자
const onTitleChange = (e) => {
console.log(e.currentTarget) // 타이핑할 때마다 발생하는 e(event)
setVideoTitle(e.currentTarget.value)
}
const onDescriptionChange = (e) => {
setDescription(e.currentTarget.value)
}
const onPrivateChange = (e) => {
setPrviate(e.currentTarget.value)
}
const onCategoryChange = (e) => {
setCategory(e.currentTarget.value)
}
여기서 e는 타이핑을 할 때마다 발생하는 event라고 보면 된다
onChange function을 만들고 나서 창을 보면
타이핑 할 때마다 업데이트된다
밑에 select도
잘 선택된다
'REACT' 카테고리의 다른 글
[클론코딩] 따라하며 배우는 노드, 리액트 시리즈 - 유튜브 사이트 만들기 #5. ffmpeg로 비디오 썸네일 생성하기 (0) | 2022.08.23 |
---|---|
[클론코딩] 따라하며 배우는 노드, 리액트 시리즈 - 유튜브 사이트 만들기 #4. Multer로 노드 서버에 비디오 저장하기 (0) | 2022.08.17 |
[클론코딩] 무비앱 시리즈 #14 (0) | 2022.07.26 |
[클론코딩] 무비앱 시리즈 #13 (0) | 2022.07.25 |
[클론코딩] 무비앱 시리즈 #12 (0) | 2022.07.25 |
댓글