
저번에는 landingpage에 비디오들을 출력했었다
1. 비어있는 비디오 디테일 페이지 생성
client-src-components-view에 VideoDetailPage 폴더를 만든다
그리고 그 안에 VideoDetailPage.js 파일을 만든다

2. 비디오 디테일 페이지를 위한 Route 만들기
새로운 페이지를 만들었으므로 App.js에 가서 Route를 해준다
일단 VideoDetailPage를 가져와준다
import VideoDetailPage from './views/VideoDetailPage/VideoDetailPage';
Route를 해주는데, 주소는 videoId로 설정한다
또한 로그인하지 않은 사람들도 접속할 수 있게 null로 설정한다
<Route exact path="/video/:videoId" component={Auth(VideoDetailPage, null)} />
landingPage에서 동영상을 클릭하면 VideoDetailPage로 넘어가야 하므로 LandingPage.js도 수정해야함!
renderCards에서 <a> 태그를 추가한다
const renderCards = Video.map((video, index)=> {
// duration은 모두 second로 표시되어있으므로 가공함
var minutes = Math.floor(video.duration/60)
var seconds = Math.floor((video.duration - minutes * 60))
return <Col key={index} lg={6} md={8} xs={24}>
<a href={`/video/post/${video._id}`}>
{/*새롭게 추가된 부분*/}
<a href={`/video/${video._id}`}>
<div style={{position: 'relative'}}>
<img style={{width:'100%'}} src={`http://localhost:5000/${video.thumbnail}`} alt="thumbnail"/>
<div className='duration'>
<span>{minutes} : {seconds}</span>
</div>
</div>
</a>
</a>
<br />
<Meta
avatar={
<Avatar src={video.writer.image}/>
}
title={video.title}
description=""
/>
<span>{video.writer.name}</span> <br />
<span style={{marginLeft:'3rem'}}> {video.views} views </span> - <span>{moment(video.createdAt).format("MMM Do YY")}</span>
</Col>
})
3. 비디오 디테일 페이지 template 만들기
video가 나올 곳의 size는 18. side video는 6으로 설정한다
<VideoDetailPage.js>
import React from 'react'
import {Row, Col, List} from 'antd';
// video는 18, side는 6
function VideoDetailPage() {
return (
<Row gutter={[16,16]}>
<Col lg={18} xs={24}>
<div style={{width: '100%', padding: '3rem 4rem'}}>
<video style={{width:'100%'}} src controls />
<List.Item
actions
>
<List.Item.Meta
avatar
title
description
/>
</List.Item>
{/*Comments*/}
</div>
</Col>
<Col lg={6} xs={24}>
Side Videos
</Col>
</Row>
)
}
export default VideoDetailPage
그래서 landingPage에서 동영상을 클릭하면


이렇게 확인할 수 있다
아직 data를 넣어주지 않아서 video가 빈 화면으로 보인다
4. mongoDB에서 비디오 데이터 가져오기
VideoDetailPage.js에서 useEffect() 함수를 사용하여 비디오 데이터를 가져올 것이다
video 정보를 가져오는 데에 videoId가 필요하므로 client에서 server로 videoId를 넘겨주는 작업을 해야한다
const videoId = props.match.params.videoId // App.js에서 설정함
const variable = {videoId : videoId}
const [VideoDetail, setVideoDetail] = useState([]) // array
useEffect(() => {
Axios.post('/api/video/getVideoDetail', variable)
.then(response => {
if(response.data.success){
setVideoDetail(response.data.videoDetail)
}else{
alert('비디오 정보를 가져오는 데에 실패했습니다.')
}
})
},[])
App.js에서 주소 형식이 '/:videoId' 였으므로 props를 이용하여 videoId를 가져왔다
이것을 server에 넘겨서 '이 id를 가진 video 데려와!' 하는 것임
video.js로 가서 데이터를 가져올 것이다
router.post('/getVideoDetail', (req, res) => {
Video.findOne({"_id": req.body.videoId}) // client에서 받은 Id로 찾음
.populate('writer') // writer의 모든 정보를 가져옴
.exec((err, videoDetail) => {
if(err) return res.status(400).send(err)
return res.status(200).json({success: true, videoDetail})
})
})
populate 안 쓰면 id만 가져올 수 있으므로 적어준다
5. 가져온 데이터 스크린에 출력하기
<VideoDetailPage.js>
import React, { useEffect, useState } from 'react'
import {Row, Col, List, Avatar} from 'antd';
import Axios from 'axios';
// video는 18, side는 6
function VideoDetailPage(props) {
const videoId = props.match.params.videoId // App.js에서 설정함
const variable = {videoId : videoId}
const [VideoDetail, setVideoDetail] = useState([]) // array
useEffect(() => {
Axios.post('/api/video/getVideoDetail', variable)
.then(response => {
if(response.data.success){
setVideoDetail(response.data.videoDetail)
}else{
alert('비디오 정보를 가져오는 데에 실패했습니다.')
}
})
},[])
if(VideoDetail.writer){
return (
<Row gutter={[16,16]}>
<Col lg={18} xs={24}>
<div style={{width: '100%', padding: '3rem 4rem'}}>
<video style={{width:'100%'}} src={`http://localhost:5000/${VideoDetail.filePath}`} controls />
<List.Item
actions // 좋아요 싫어요
>
<List.Item.Meta
avatar={<Avatar src= {VideoDetail.writer.image}/>}
title={VideoDetail.writer.name}
description={VideoDetail.description}
/>
</List.Item>
{/*Comments*/}
</div>
</Col>
<Col lg={6} xs={24}>
Side Videos
</Col>
</Row>
)
} else{
return (
<div>... loading</div>
)
}
}
export default VideoDetailPage
return에서 if else 구문을 쓰지 않으면 렌더링이 되기 전에 writer의 image, name의 정보를 얻어오려 하여 오류가 난다
다 완료하면

이렇게 잘 뜬다!
쇼츠를 다운받아서 그런지 비율이 이상해서 너무 크다 ㅜㅜ
댓글