1. lib ํด๋ > api.js
export const videoUrl = `https://youtube.googleapis.com/youtube/v3/search?part=snippet&chart=mostPopular&maxResults=30&q=css3®ionCode=kr&type=video&key=๋ณธ์ธํค`
→ ์ธ์ฆํค ๋ ธ์ถ๋๋ฉด ์๋จ, ๋์ ๊ณ ์ ํ ์ ๋ณด๋ผ์ ํดํน๋๊ฑฐ๋ ๋์ฉ๋ ์ ์์ด์ ๊ทธ ๋ ์๊ธฐ๋ ๋ฌธ์ ๋ ์๊ธฐ ์ฑ ์, ๋ฐ๋ผ์ ํ๊ฒฝ ๋ณ์๋ก ์ฒ๋ฆฌํด์ค์ผ ํจ
2. ํ๊ฒฝ๋ณ์ ๋ง๋๋ ๋ฒ
react ๊ณต์ ๋ฌธ์์ ํ๊ฒฝ๋ณ์ ์ค์ ๋ถ๋ถ ์๋๋ฐ ๋ชป ์ฐพ์ ๋์ค์ ์ฒจ๋ถํด์ฃผ์ ๋ค๊ณ ํจ
- ์ด๋ค ํด๋ ์์ ๋ง๊ณ ์์ ๋ฐ์ .env ํ์ผ ๋ง๋ค๊ธฐ
- API_KEY=๋ด ํค๊ฐ → ๋ ธ๋์์ ์ฌ์ฉํ๋ ํค๊ฐ
- REACT_APP_API_KEY=๋ด ํค๊ฐ → ๋ฆฌ์กํธ์์ ์ฌ์ฉํ๋ ํค๊ฐ
- ๋ ๋ค ๋์ด์ฐ๊ธฐ ์๋จ, ๋์ด์ฐ๊ธฐ ๊น์ง ํ๊ฒฝ ๋ณ์๋ก ์ธ์
- api.js ๋ก ๊ฐ์ const API_KEY=process.env.REACT_APP_API_KEY → import ํด์ค ํ์ ์๊ณ ์ด๋ ๊ฒ ๋ฃ์ด์ฃผ๋ฉด ๋ถ๋ฌ์จ ๊ฑฐ์
- ๊ทธ๋ฆฌ๊ณ ์์ videoUrl ๋ณ์ ์ง์ ํด์คฌ๋ ์ฃผ์์ ์๋ ํค๊ฐ ์์ ๊ณ ${API_KEY} ์ด๋ ๊ฒ ๋ฃ์ด์ฃผ๋ฉด ํค ๊ฐ์ด ๋ค์ด๊ฐ๋ ๊ฑฐ์
- videolist ๋ก ๊ฐ์ import { videoUrl } from '../../lib/api'; ํด์ฃผ๊ณ dispatch(getVideoList(videoUrl)) ๋ก ๋ฃ์ด์ฃผ๋ฉด ์ฟผ๋ฆฌ๊ฐ์ผ๋ก ๋์ด๊ฐ
- ํ๊ฒฝ๋ณ์ ์์ฑ ํ์๋ ๊ผญ ์๋ฒ ๊ป๋ค๊ฐ ๋ค์ ๋์ํด์ผ ์ ์ฉ์ด ๋จ
- searchform ๋ถ๋ถ์ api ๋ ๊ฐ์ ธ์์ ํ๊ฒฝ๋ณ์ ์ฒ๋ฆฌํด์ฃผ๊ธฐ ( url ์์ ๋ณ์๊ฐ ์์ )
export function searchUrl(input){
return `https://youtube.googleapis.com/youtube/v3/search?part=snippet&maxResults=30&q=${input}®ionCode=kr&type=video&key=${API_KEY}`
}
→ api.js ์์ url ์์ ๋ณ์๋ฅผ ์ธ์๋ก ๋ฃ์ ํจ์๋ฅผ ์์ฑ
- searchform index ํ์ผ๋ก ๊ฐ์ import { searchUrl } from '../../../lib/api';
const onSearch = (input) =>{
const url =searchUrl (input)
dispatch(getVideoList(url))
navigate('/')
}
→ app.js ์์ ๊ฐ์ ธ์จ searchUrl ์ input ์ ๋ฃ์ ๋ณ์๋ก ์ค์ ํ ๋ค ์ฟผ๋ฆฌ๊ฐ์ผ๋ก ํด๋น ๋ณ์๋ฅผ ์ธ์๋ก ๋๊ฒจ์ฃผ๋๋ก ์์
3. pages > search.js ์์ฑํด์ ๊ฒ์ํ๋ฉด ์์ ๋ค๋ฅธ ํ์ด์ง๋ก ์ด๋ํ๋๋ก
- app.js ์์ <Route path="/search" element={<Search />} />
- search.js์ ๊ธฐ๋ณธ ์ธํ
import React from 'react';
import SideMenu from '../components/SideMenu';
import VideoList from './../components/VideoList/index';
const Search = () => {
return (
<>
<SideMenu />
<section className='main-content'>
<VideoList />
</section>
</>
);
};
export default Search;
→ home.js ์ ๋๊ฐ์ด ๊ตฌ์ฑ
1) ๋ ์ด์์ ๊ด๋ฆฌ๋ฅผ redex ๋ก
- videoSlice ๋ก ๊ฐ์
- initialState ์ listLayout: 'grid', ์ถ๊ฐ
reducers:{
videoListLayout: (state, action) =>{
state.listLayout=action.payload
}
},
→ ํด๋น grid ๋ ์ด์์ ๋์ค๋๋ก ๋ง๋๋ ๊ฒ
- ๋งจ ํ๋จ์ export const {videoListLayout} = videoSlice.actions
2) grid ๋ผ๋ ๊ฐ์ reducer ๋ก, url ๋ฟ ์๋๋ผ ๋ ์ด์์๋ dispatch
- SearchForm ์ผ๋ก ์์ onSearch ํ๋ฉด dispatch(videoListLayout('list')) ๊ฐ ์ฟผ๋ฆฌ๊ฐ ๋์ด๊ฐ๋๋ก ์ค์
- videoListLayout ๋ import
- list ์ธ์ง gird ์ธ์ง ์ฝ์ด์ ํด์ผ ํ๋๊น Search.js ๋ก ์์
- import { useSelector } from 'react-redux';
- const display = useSelector((state)=>state.video.listLayout);
→ display ๋ onsearch ํด์ Search ํ์ด์ง๋ก ๋์ด๊ฐ๋ฉด ๋ ์ด์์์ list ๋ก css ๋ฅผ ๋ณ๊ฒฝํด์ค ๊ฒ์
- VideoList ๋ก ์์ display props ๋ฐ์์ฃผ๊ณ
- <ul className={display==='grid'?'videoList VideoGrid':'videoList VideoRowList'} > ๋ก ์์
→ display ๊ฐ gird ์ผ ๊ฒฝ์ฐ VideoGrid' ๋ฅผ, ์๋๋ฉด VideoRowList ๋ฅผ ์ ์ฉ
- css ๋ง๋ค๊ธฐ
- Home.js ๋ก ๊ฐ์
import { useEffect } from 'react';
import { useSelector,useDispatch } from 'react-redux';
import { videoListLayout } from '../store/video/videoSlice';
const dispatch = useDispatch();
const display = useSelector((state) => state.video.listLayout)
useEffect(()=>{
dispatch(videoListLayout('grid'))
},[])
<VideoList display={display} />
!!!! ์ฃผ์ !!!!
ํ๊ฒฝ ๋ณ์ ํ์ผ ๋ฌด์ํ๊ณ ์ฌ๋ ค์ผ ํจ
ignore ํ์ผ ์์ #API_KEY .env ํด์ฃผ๊ธฐ
'๐ฑ SeSac > ๊ณต๋ถ ๊ธฐ๋ก (๋ณต์ตํ๋ฉฐ ์ ๋ฐ์ดํธ ์ค)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[220725] ์ ํ๋ธ ํด๋ก ์ฝ๋ฉ 5 (0) | 2022.09.15 |
---|---|
[220722] ์ ํ๋ธ ํด๋ก ์ฝ๋ฉ 4 (0) | 2022.09.15 |
[220720~220721] ์ ํ๋ธ ํด๋ก ์ฝ๋ฉ 2 (0) | 2022.09.15 |
[220718] ์ ํ๋ธ ํด๋ก ์ฝ๋ฉ 1 (1) | 2022.09.15 |
[220711 / Day 40] ์ผํ๋ชฐ ๋ง๋ค๊ธฐ 2 (0) | 2022.07.11 |