Jane K 2022. 9. 15. 15:42

1. ๋กœ๋”ฉ ์ถ”๊ฐ€

1) VideoList

- useEffect ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ api ํ˜ธ์ถœ, ์‹œ๊ฐ„์— ๋”œ๋ ˆ์ด๊ฐ€ ์ƒ๊ธฐ๋ฉด ๋งˆ์šดํŒ…์ด ๋์„ ๋•Œ api ๋ฅผ ๋ชป ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊น€ ๋”ฐ๋ผ์„œ ๋กœ๋”ฉ ํ™”๋ฉด์ด ๋œจ๋Š” ๊ฒŒ ํ•„์š”ํ•จ

- npm react-spinners ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜, npm install --save react-spinners

- npm ์‚ฌ์ดํŠธ์— ๊ฒ€์ƒ‰ํ•ด๋ณด๋ฉด Demo Page ์— ๋กœ๋”ฉ ํ™”๋ฉด์— ๋œฐ ๋‹ค์–‘ํ•œ ์•„์ด์ฝ˜ ์ œ๊ณต, Storybook ์—์„œ๋Š” ํ•ด๋‹น ์•„์ด์ฝ˜์˜ ๊ตฌ์ฒด์  ์ฝ”๋“œ ์ œ๊ณต

 

import ClipLoader from "react-spinners/ClipLoader";

 

if(loading){

    return <ClipLoader color={color} loading={loading} cssOverride={override} size={150} />

   }

- return ๋ฌธ ๋ฐ–์— if ๋ฌธ์œผ๋กœ ๋กœ๋”ฉ์ด ์—†์œผ๋ฉด ์ปจํ…์ธ ๊ฐ€ ๋‚˜์˜ค๊ณ  ๋กœ๋”ฉ์ด ์žˆ์œผ๋ฉด ๋กœ๋”ฉ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ณด์ด๋„๋ก

- loading ๊ฐ’์€ ๋ฆฌ๋•์Šค๋กœ ๊ฐ€์ ธ์˜ฌ ๊ฒƒ์ž„

- ClipLoader ๋Š” react-spinners ์˜ ๊ธฐ๋Šฅ์ ์ธ ๊ฒƒ์ด ์•„๋‹ˆ๊ณ  ๋ชจ์–‘์ž„ ๋”ฐ๋ผ์„œ ์Šคํ† ๋ฆฌ๋ถ์—์„œ ์›ํ•˜๋Š” ๋ชจ์–‘์„ ๊ฐ€์ ธ๋‹ค๊ฐ€ ์“ฐ๋ฉด ๋จ

- ์Šคํ† ๋ฆฌ๋ถ์—์„œ ๊ฐ€์ ธ์˜ฌ ๋•Œ control ์—์„œ ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๊ฐ’์œผ๋กœ ์„ค์ •ํ•ด์„œ ์ฝ”๋“œ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜๋„ ์žˆ์Œ (์ƒ‰๊น”, ์• ๋‹ˆ๋ฉ”์ด์…˜ ์‹œ๊ฐ„ ๋“ฑ)

- ์ปดํฌ๋„ŒํŠธ๋Š” ๋”ฐ๋กœ ํด๋ž˜์Šค ๋„ค์ž„์„ ์ง€์ •ํ•˜์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ธ๋ผ์ธ ์Šคํƒ€์ผ๋กœ ์ค˜์•ผ ํ•จ

- ์Šคํ† ๋ฆฌ๋ถ์—์„œ cssOverride ๊ฐ€ ๊ทธ๊ฒƒ์ธ๋ฐ control ์—์„œ raw ํ•ด์ฃผ๋ฉด ์Šคํƒ€์ผ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๊ณ  ์ƒ๋‹จ์— show code ํ•˜๋ฉด ํ•ด๋‹น ์Šคํƒ€์ผ์˜ ์ฝ”๋“œ๊ฐ€ ๋‚˜์˜ด, ๋ณต์‚ฌ ๋ถ™์—ฌ๋„ฃ๊ธฐ

 

2) videoSlice

- initialState ์— ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ loading: true, ๋„ฃ์–ด๋†“๊ธฐ

- extraReducers ์—๋‹ค๊ฐ€ fulfilled ๋ง๊ณ  ๊ฐ’์„ ํŒ๋‹จํ•˜๊ณ  ์žˆ๋Š” ์ƒํƒœ๋ฅผ ์ถ”๊ฐ€

builder.addCase(getVideoList.pending,(state,action)=>{

            state.loading=true;

        })

pending ์ƒํƒœ์—์„œ loading ์„ true

builder.addCase(getVideoList.fulfilled,(state,action)=>{

            state.data=action.payload;

            state.loading=false;

        })

→ ๊ธฐ์กด์— ์žˆ๋˜ ๊ฒƒ ์ˆ˜์ •, ๋‚˜์˜ค๋ฉด loading ์„ false

builder.addCase(getVideoList.rejected,(state,action)=>{

            console.log('์•ก์…˜ํŽ˜์ด๋กœ๋“œ',action.payload)

            state.loading=true;

        })

rejected ๊ฑฐ๋ถ€๋์„ ๋•Œ loading ์„ true

 

3) VideoList

- loading ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ

- ๊ธฐ์กด์— ์žˆ๋˜ ๋ฐ์ดํ„ฐ ๋ถˆ๋Ÿฌ์˜จ ๊ฒƒ๊ณผ ์ถ•์•ฝํ•ด์„œ ์„ค์ •

- const {data, loading} = useSelector((state) => state.video)

- ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ž˜ ๋œธ

 

 

 

2. ๋™์˜์ƒ ํ˜„์žฌ ๋‚ ์งœ ๊ธฐ์ค€ ๋ช‡์ผ ์ „ ์˜ฌ๋ ธ๋Š”์ง€ ๋‚ ์งœ ํ‘œ์‹œ

- ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ ๋ณด๋ฉด snippet ์— publishedAt ์— ์‹œ๊ฐ„์ด ๋‚˜์˜ค๋Š”๋ฐ ํ˜„์žฌ ์‹œ๊ฐ„๊ณผ ๋น„๊ตํ•ด์„œ ๋นผ๊ณ  ์‹œ๋ถ„์ดˆ๋กœ ๋‚˜๋ˆ ์„œ ํ‘œ์‹œํ•ด์ค„ ๊ฒƒ

 

1) VideoItem

- ๊ทธ๋ƒฅ <p className='date'>{item.publishedAt}</p> ๋กœ ์ถ”๊ฐ€ํ•˜๋ฉด 2019-06-03T23:00:05Z ์ด๋ ‡๊ฒŒ๋งŒ ๋‚˜์˜ด

 

2) lib > common.js ์ƒ์„ฑ

- export function convertDate(dateValue) ํ•˜๋‚˜ ์ƒ์„ฑ

- const publishedDate = new Date(dateValue); → publish ๋œ ์‹œ๊ฐ„์˜ ๊ฐ์ฒด ๋ฐ›์•„์˜ด

- const currentDate = new Date(); → ํ˜„์žฌ ์‹œ๊ฐ„์˜ ๊ฐ์ฒด ๋ฐ›์•„์˜ด

- const seconds = (currentDate.getTime()-publishedDate.getTime()) / 1000 → 1970๋…„์„ ๊ธฐ์ค€์œผ๋กœ ์ง€์ •ํ•œ ๋‚ ์งœ๊นŒ์ง€์˜ ์ดˆ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” getTime ๋ฉ”์„œ๋“œ๋กœ ํ˜„์žฌ์‹œ๊ฐ„ ๋นผ๊ธฐ publish ์‹œ๊ฐ„

- ๋”ฐ๋ผ์„œ ๋บ€ ์‚ฌ์ด ๊ฐ„๊ฒฉ์œผ๋กœ 1000 ์œผ๋กœ ๋‚˜๋ˆ ์„œ ์ดˆ, 60 ์œผ๋กœ ๋‚˜๋ˆ ์„œ ๋ถ„, ๋ช‡์œผ๋กœ ๋‚˜๋ˆ ์„œ ์‹œ ๋กœ ๋งŒ๋“ค ๊ฒƒ

let result;

if (seconds<10){

  result = `๋ฐฉ๊ธˆ ์ „`;

}else if (seconds < 60) {

  result = `${seconds}์ดˆ ์ „`;

}else if (seconds < 3600) {

  result =  `${Math.floor(seconds / 60)}๋ถ„ ์ „`;

}else if (seconds < 86400) {

  result = `${Math.floor(seconds / 3600)}์‹œ๊ฐ„ ์ „`;

} else if (seconds < 604800) {

  result = `${Math.floor(seconds / 86400)}์ผ ์ „`;

} else if (seconds < 2592000) {

  result = `${Math.floor(seconds / 604800)}์ฃผ ์ „`;

} else if (seconds < 31536000) {

  result = `${Math.floor(seconds / 2592000)}๋‹ฌ ์ „`;

} else {

  result = `${Math.floor(seconds / 31536000)}๋…„ ์ „`;

}

return result;

 

3) VideoItem

- ์œ„์— ๊ฒƒ import, import { convertDate } from '../../lib/common';

- ์•„๊นŒ ๋งŒ๋“ค์—ˆ๋˜ <p className='date'>{item.publishedAt}</p> ๋ถ€๋ถ„์„

- <p className='date'>{convertDate(item.publishedAt)}</p> ๋กœ ์ˆ˜์ •

 

 

 

3. ์ƒ์„ธํŽ˜์ด์ง€ ๋™์˜์ƒ ๋ชฉ๋ก ์ผ๋ ฌ๋กœ ์ˆ˜์ •

1) Watch

- videoData ๋ถ€๋ถ„์„ data ๋กœ ๋ฐ”๊ฟ”์ค˜์„œ ํ†ต์ผ์‹œ์ผœ์ฃผ๊ธฐ

- const {data} = useSelector((state) => state.video);

2) Home

- const display = useSelector((state) => state.video.listLayout) ๋ถ€๋ถ„์„

- const {listLayout} = useSelector((state) => state.video) ๋กœ ์ˆ˜์ •

- <VideoList display={display} /> ๋ถ€๋ถ„์„

- {listLayout &&  <VideoList display={listLayout} />} ๋กœ ์ˆ˜์ •

3) Search

- const display = useSelector((state)=>state.video.listLayout); ๋ถ€๋ถ„์„

- const {listLayout} = useSelector((state)=>state.video.listLayout); ๋กœ ์ˆ˜์ •

- <VideoList display={display} /> ๋ถ€๋ถ„์„

- {listLayout &&  <VideoList display={listLayout} />} ๋กœ ์ˆ˜์ •

 

4) Watch

- <ul className='watchList' > ํด๋ž˜์Šค ๋„ค์ž„์— VideoRowList ์ถ”๊ฐ€ํ•ด์„œ style ์„ค์ •

 

 

 

4. ์ฃผ๋ง ์ˆ™์ œ : ๋™์˜์ƒ ํ•˜๋‹จ์— ์ฑ„๋„ ์ •๋ณด ๋œจ๋„๋ก ์„ค์ •ํ•˜๊ธฐ

1) ํ•˜๋Š” ๋ฐฉ๋ฒ•

- youtube.api ์‚ฌ์ดํŠธ๋กœ ๊ฐ€์„œ Reference > video > list

- part ๋ถ€๋ถ„์— statistics ๋ผ๊ณ  ์ ๊ธฐ, + ๋ˆŒ๋Ÿฌ์„œ snippet ๋„ ์ถ”๊ฐ€

- show ์ฝ”๋“œ

https://youtube.googleapis.com/youtube/v3/videos?part=statistics&part=snippet&chart=mostPopular&maxResults=30®ionCode=kr&key=๋ณธ์ธํ‚ค

- ์ฃผ์†Œ์— ๋ณต๋ถ™ํ•˜๋ฉด statistics ๊ฐ€ ์žˆ๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์Œ

- ์„œ์น˜๊ฐ€ ์žˆ์„ ๋•Œ๋งŒ ์ € ๊ฐ’์ด ์žˆ๋„๋ก ํ•ด์ค˜์•ผ ํ•จ

- ์ฑ„๋„ ์ •๋ณด ๋ถ€๋ถ„์€ channels > list ์— part : snippet, ~ channelId ๊ผญ ์ถ”๊ฐ€ํ•ด์„œ ๋ณด๋ฉด ์ฑ„๋„ ์ •๋ณด๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Œ

- ๊ทธ๋ž˜์„œ ์ƒ์„ธํŽ˜์ด์ง€ ์•„๋ž˜์— ๋„ฃ์„ ์ปดํฌ๋„ŒํŠธ์— ์œ„ ์ •๋ณด๋ฅผ ๋ฟŒ๋ ค์„œ ๋‚˜์˜ค๋„๋ก ๋งŒ๋“ค๊ธฐ