[220722] ์ ํ๋ธ ํด๋ก ์ฝ๋ฉ 4
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 ์ฝ๋
- ์ฃผ์์ ๋ณต๋ถํ๋ฉด statistics ๊ฐ ์๋ ๊ฑธ ๋ณผ ์ ์์
- ์์น๊ฐ ์์ ๋๋ง ์ ๊ฐ์ด ์๋๋ก ํด์ค์ผ ํจ
- ์ฑ๋ ์ ๋ณด ๋ถ๋ถ์ channels > list ์ part : snippet, ~ channelId ๊ผญ ์ถ๊ฐํด์ ๋ณด๋ฉด ์ฑ๋ ์ ๋ณด๊ฐ ํฌํจ๋์ด ์์
- ๊ทธ๋์ ์์ธํ์ด์ง ์๋์ ๋ฃ์ ์ปดํฌ๋ํธ์ ์ ์ ๋ณด๋ฅผ ๋ฟ๋ ค์ ๋์ค๋๋ก ๋ง๋ค๊ธฐ