SMALL
ํ๋ก์ ํธ ๋ฉ์ธํ์ด์ง์์
ํ์ํ ์ ๋ณด๋ค์ api - axios get ํด์ ๊ฐ์ ธ์ค๊ณ ,
๊ทธ ์ ๋ณด๋ค์ ํ๋์ ๊ฐ์ฒด๋ก ๋ฌถ์ด, ๋ฐฐ์ด state (useState) ์ ํ๋์ฉ ๋ด๊ณ map์ผ๋ก ๋๋ฆฌ๋ฉด์ ์ถ๋ ฅํ๋ค.
<Thumbnail>์ ์ปดํฌ๋ํธ !
๊ทธ ์ธ์๋ input์ ๋ถ์ฌํ๋ onKeyDown ์์ฑ ๋ฑ์ ๋ฐฐ์ ๋ค.
์ด๋ฒ์๋ trim() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ์ ํจ์ฑ ๊ฒ์ฌ๋ ์ถ๊ฐ !
(๋ค๋ฅธ ๋ถ๋ค์ด ์ฐ์ ์ฝ๋๋ ์์ /์คํ์ผ์ปดํฌ๋ํธ ๋ถ๋ถ์ ์๋ต)
import { useEffect, useState } from 'react';
import styled from 'styled-components';
import HeaderSlider from '../sliders/HeaderSlider';
import { useMostPopularVideos } from '../../hooks/useMostPopularChannel';
import { getMostChannelInfo, getMostPopularThumbnails } from '../../api/dataApi';
import Thumbnail from '../main/Thumbnail';
import { useNavigate } from 'react-router-dom';
import BodySlider from '../sliders/BodySlider';
export default function Main() {
const navigate = useNavigate();
const [channelInfos, setChannelInfos] = useState([]);
const { data: videos, isLoading, isError } = useMostPopularVideos();
const [searchTerm, setSearchTerm] = useState('');
const searchIconSrc = 'https://s3.ap-northeast-2.amazonaws.com/cdn.wecode.co.kr/icon/search.png';
const keyWords = ['๋จน๋ฐฉ', '์ฌํ', '์ํ', '์ด๋', '๋ทฐํฐ', 'ํจ์
'];
const order = ['1st', '2nd', '3rd', '4th', '5th'];
useEffect(() => {
const getThumbnails = async () => {
if (videos) {
const newChannelInfos = [];
for (const video of videos.slice(0, 5)) {
const channelTitle = video.snippet.channelTitle;
const channelThumbnail = (await getMostPopularThumbnails(video.snippet.channelId)).high.url;
const channelCustomUrl = await getMostChannelInfo(video.snippet.channelId);
const channelUrl = `https://www.youtube.com/${channelCustomUrl}`;
const channelInfo = { channelTitle, channelThumbnail, channelUrl };
// console.log(channelThumbnail);
newChannelInfos.push(channelInfo);
}
setChannelInfos(newChannelInfos);
}
};
getThumbnails();
}, [videos]);
const handleSearchInputChange = (e) => {
setSearchTerm(e.target.value);
};
// Enter ํค๋ฅผ ๋๋ฌ ๊ฒ์ (=> ๋ฆฌ์คํธํ์ด์ง๋ก ์ด๋)
const handleSearchEnter = (e) => {
if (e.key === 'Enter') {
if (!searchTerm.trim()) {
return alert('๊ฒ์์ด๋ฅผ ์
๋ ฅํด์ฃผ์ธ์.');
}
navigate(`/list/${searchTerm}`);
}
};
// ๊ฒ์์์ด์ฝ ๋๋ฌ ๊ฒ์ (=> ๋ฆฌ์คํธํ์ด์ง๋ก ์ด๋)
const handleSearchClick = () => {
if (!searchTerm.trim()) {
return alert('๊ฒ์์ด๋ฅผ ์
๋ ฅํด์ฃผ์ธ์.');
}
navigate(`/list/${searchTerm}`);
};
const handleKeyWordClick = (keyword) => {
navigate(`/list/${keyword}`);
};
const handleChannelClick = (channelUrl) => {
window.open(channelUrl, '_blank');
};
if (isLoading) return <div>..Loading</div>;
if (isError) return <div>{isError.message}</div>;
return (
<MainWrap>
<HeaderSlider />
<MainSearch>
<SearchInputBox>
<input
id="search-input"
type="search"
placeholder="์ํ๋ ์ฃผ์ ๋ฅผ ๊ฒ์ํด๋ณด์ธ์ !"
value={searchTerm}
onChange={handleSearchInputChange}
onKeyDown={handleSearchEnter}
/>
<img src={searchIconSrc} onClick={handleSearchClick} />
</SearchInputBox>
<SearchKeyWord>
{keyWords.map((keyword) => {
return (
<KeywordText key={keyword} onClick={() => handleKeyWordClick(keyword)}>
#{keyword}
</KeywordText>
);
})}
</SearchKeyWord>
</MainSearch>
<BodySlider />
<MainBest>
<MainBestTitle>
<h3>Best YouTuber</h3>
<p>์ด๋ฌ์ ์ธ๊ธฐ ์ ํ๋ฒ</p>
</MainBestTitle>
<MainBestContWrap>
{channelInfos.map((channelInfo, index) => (
<BestYoutuber>
<p>{order[index]}</p>
<Thumbnail
handleChannelClick={handleChannelClick}
channelUrl={channelInfo.channelUrl}
key={index}
src={channelInfo.channelThumbnail}
alt={`Thumbnail ${index + 1}`}
/>
<p>{channelInfo.channelTitle}</p>
</BestYoutuber>
))}
</MainBestContWrap>
</MainBest>
</MainWrap>
);
}
SMALL