안녕하세요
2주차 유튜브 API(5) - 구독 기능, 좋아요 표시한 동영상, 리덕스 이식 본문
https://youngentry.github.io/week2-youtube-api/
React App
youngentry.github.io
구독 기능 만들기
=> 버튼을 클릭하면 눌려있는 표시로 바뀐다.
useEffect(() => {
axios
.get(`https://youtube.googleapis.com/youtube/v3/videos?part=snippet&chart=mostPopular&maxResults=25&key=${apiKey}`)
.then((res) => {
dispatch(setPopularVideo([...res.data.items]));
})
.catch((error) => console.log("error", error));
}, []);
=> App.js에서 GET 요청으로 인기 동영상을 받아옵니다.
=> 받아온 동영상 목록을 popularVideo state에 저장합니다.
=> 구독한 채널을 사이드에 별도로 렌더링하기 위해서는 여러 컴포넌트에 state를 사용해야 한다는 판단에 리덕스로 state를 옮겼습니다.
=> 구독한 채널을 사이드바에서 볼 수 있도록 했습니다.
Video.js(동영상페이지)에서 좋아요, 싫어요, 구독중 상태를 관리할 스테이트를 만듭니다.
const tempListIndex = popularVideo.findIndex((data) => data.id === mockVideo.id);
const [isLike, setIsLike] = useState(popularVideo[tempListIndex].isLike);
const [isDislike, setIsDislike] = useState(popularVideo[tempListIndex].isDislike);
const [isSubscribed, setIsSubscribed] = useState(popularVideo[tempListIndex].isSubscribed);
=> 초기값은 popularVideo에서 동영상페이지의 id와 일치하는 동영상의 좋아요, 싫어요, 구독중 상태로 만듭니다.
=> 동영상페이지를 나갔다 돌아올 때도 버튼이 눌려있는 상태를 유지합니다.
subscribe 함수를 실행하면 subscribeList에 데이터를 추가합니다.
const subscribe = () => {
setIsSubscribed(!isSubscribed);
dispatch(addSubscribe({ title: mockVideo.snippet.channelTitle, channelId: mockVideo.snippet.channelId }));
};
// html
<div className={`subscribe`} onClick={() => subscribe()}>구독</div>
=> 구독하기 버튼을 누르면 버튼이 눌리는 상태로 변하게 되고,
=> subscribeList state에 구독한 채널의 이름과 채널 id를 추가합니다.
=> channel Id를 함께 담아 채널 이름을 클릭하면 해당 채널로 이동하는 기능을 구현할 것입니다.
다음으로는 구독 버튼을 클릭하면 subscribeList state에 저장한 데이터를 이용해 NavSide에 나타나게 합니다.
=> 구독 버튼을 클릭하면 이렇게 사이드 네비에 나타나도록 합니다.
subScribeList state를 NavSide component에 가져옵니다.
const NavSide = () => {
const subscribeListSlice = useSelector((state) => state.subscribeListSlice);
구독 목록이 비어있다면 "없음"을 출력하고 구독한 채널이 있다면 해당 채널을 표시합니다.
<div className="side-container">
<strong>구독</strong>
{subscribeListSlice.length ? (
subscribeListSlice.map((channel) => {
return <div className="subscribe-side-list">{channel.title}</div>;
})
) : (
<div className="subscribe-side-list">없음</div>
)}
</div>
a 태그를 이용하여 해당 채널을 새 탭에서 띄우는 기능을 구현합니다.
(채널 페이지까지 구현하기 위해서는 너무 오래 걸릴 것 같아 새 탭 띄우기로 대체합니다.)
const channelBaseUrl = "https://www.youtube.com/channel/";
=> 위의 url 뒤에 channelId를 입력하면 됩니다.
<div className="subscribe-side-list">
<a href={`${channelBaseUrl}${channel.channelId}`} target="_blank">
{channel.title}
</a>
</div>
=> target="_blank" 속성을 주게 되면 새 탭에서 띄웁니다.
=> 채널 글씨에 마우스를 얹으니 연결 링크가 나타납니다.
subscribe 페이지도 subscribeList를 가져다 만들어 봅시다.
const Subscribe = () => {
const channelBaseUrl = "https://www.youtube.com/channel/";
const subscribeList = useSelector((state) => state.subscribeListSlice);
console.log(subscribeList);
return (
<div className="subscribe">
<h2>구독한 채널 목록</h2>
{subscribeList.map((channel, index) => {
return channel ? (
<div key={index}>
<a href={`${channelBaseUrl}${channel.channelId}`} target="_blank">
{channel.title}
</a>
</div>
) : (
<div key={index}>{null}</div>
);
})}
</div>
);
};
=> NavSide 만들때랑 똑같이 만들면 됩니다.
=> 잘 됩니다.
Like, Dislike component도 동일한 방식으로 만드는 것이 관리도 쉽고 현실적이겠지만...
구독 기능 구현과 완전하게 똑같은 과정을 반복하면 될 뿐이어서💦
data에 isLike 속성을 넣어주고, isLike 속성을 가진 영상을 출력하도록 했습니다.
setLike(state, action) {
state[action.payload.tempListIndex].isLike = action.payload.isLike;
},
=> setLike 함수를 실행하면 popularVideo의 데이터에 isLike 속성을 업데이트 합니다.
=> isDisLike, isLike, isSubscribed 데이터가 업데이트 된 모습
Like 페이지에서 isLike 속성을 가진 영상을 골라서 렌더링합니다.
const Like = () => {
const popularVideo = useSelector((state) => state.popularVideo);
return (
<div>
<div>좋아요 표시한 동영상</div>
{popularVideo.map((data, index) => {
return data.isLike ? (
<div key={index}>
<div>
<ReactPlayer className="videoPlayer" url={`https://www.youtube.com/embed/${data.id}&origin=http://localhost:3000/`} muted={true} playing={false} width="100%" height="100%" />
</div>
<strong> {data.snippet.title}</strong>
</div>
) : (
<div key={index}>{null}</div>
);
})}
</div>
);
};
=> 좋아요 표시를 남긴 동영상과 동영상의 제목을 같이 나타나도록 했습니다.
=> 싫어요 페이지도 똑같은 방식으로 만들어 줍니다.
리덕스 이식 과정은 store.js 코드로 대체합니다.
(지금 프로젝트 만들다 시간 지나면 까먹어서 다음 프로젝트 할 때는 어차피 또 어떻게하더라... 하면서 찾아봐야 합니다.
기억하려면 시간들여 반복하는 수 밖에 없죠.🙄)
import { configureStore, createSlice } from "@reduxjs/toolkit";
const popularVideo = createSlice({
name: "popularVideo",
initialState: [],
reducers: {
setPopularVideo(state, videoList) {
return [...videoList.payload];
},
setLike(state, action) {
state[action.payload.tempListIndex].isLike = action.payload.isLike;
},
setDislike(state, action) {
state[action.payload.tempListIndex].isDislike = action.payload.isDislike;
},
setSubscribe(state, action) {
state[action.payload.tempListIndex].isSubscribed = action.payload.isSubscribed;
},
},
});
export let { setPopularVideo, setLike, setDislike, setSubscribe } = popularVideo.actions;
const subscribeListSlice = createSlice({
name: "subscribeListSlice",
initialState: [],
reducers: {
addSubscribe(state, action) {
return [...state, action.payload];
},
},
});
export let { addSubscribe } = subscribeListSlice.actions;
export default configureStore({
reducer: {
popularVideo: popularVideo.reducer,
subscribeListSlice: subscribeListSlice.reducer,
},
});
4번 구독기능 마지막 기능 제외하고 구현 완료🙆♀️
➕구독한 영상 상단으로 기능 추가하기
'복습스터디과제' 카테고리의 다른 글
2주차 유튜브 API(7 - ERROR) - async-await 이용하여 Api Class를 만들어 봅시다. (0) | 2023.01.28 |
---|---|
2주차 유튜브 API(6) - axios params 로 보기 좋게 GET요청하기 (0) | 2023.01.28 |
2주차 유튜브 API(4) - 썸네일에 마우스 올리면 재생하기 (0) | 2023.01.23 |
2주차 유튜브 API(3) - 동영상 페이지 만들기 (0) | 2023.01.23 |
2주차 유튜브 API(2) - Youtube API 받아오기 (0) | 2023.01.22 |