SMALL
1. 문제점
- 프로젝트에서 음악 재생 수 즉, 스트리밍 수에 따른 순위를 만들기 위해 음악이 재생되고 X초 후에 api를 요청하여 조회수를 1회 늘리는 방법을 구현해야 했다.
- X초 후에 api를 요청하여 조회수를 1씩 늘리려고 하는 이유는 다른 사람들이 편법을 사용해 스트리밍 수를 조작할 수 있기 때문에, 이를 막기 위해 제한 사항을 만들었음
2. 시도한 방법
- audio 태그를 사용했을 때, 분명히 현재 얼마나 재생됐는지, 혹은 재생하고 있는 시간이 몇 분, 몇 초인지 알 수 있는 event가 있을 것이라 생각했고, 대부분 current 관련된 이름으로 되어있을 것이라 생각해 audio current 관련된 것들을 모두 검색했고, currentTime이라는 event를 하나 알게 되었다.
- 그리고 이를 가지고 어떻게 구현할지 미리 구상을 짜고, 코드를 작성했다.
- audio에 ref 지정
- 지정한 ref의 currentTime event를 가지고 currentTime이 3초일 때, console.log를 찍어보았다.
const audioRef = useRef<HTMLAudioElement>(null);
<div>
<audio
ref={audioRef}
controls
onTimeUpdate={handleTimeUpdate}
src="01-Copland-Danzon_Cubano-Bernstein1963.mp3"
></audio>
</div>
- currentTime의 이벤트는 onTimeUpdate에 들어있음으로 onTimeUpdate를 실행할 함수를 먼저 만들고, 그 안에 작성하였음
const handleTimeUpdate = () => {
if (audioRef.current?.currentTime && audioRef.current.currentTime >= 3) {
console.log("3초가 지났습니다.")
}
};
- 위와 같이 했을 때, 음악의 시간이 3초가 넘어가면 console이 찍혔다
- 문제점
- 3초가 지난 후에는 console이 재생하는 음악의 시간이 지날 때마다 console이 계속 찍히게 됨
- 음악을 만약 4초에 시작하면 console이 바로 찍히게 됨
- 위와 같은 문제점을 만났고, api가 계속 요청되면 결국 편법으로 조회수를 올리는 것이기 때문에, 위의 방법에서 조금 더 로직을 추가해야 했음
3. 시도한 방법
추가된 로직
- timer이라는 값을 하나 만들고, 이를 state로 지정하여 관리하기로 했음
- currentTime을 지정하고, 재생될 때마다 아까 console이 계속 찍혔으니, timer을 계속 증가시키고, timer가 지정된 숫자(초 단위는 아니었음)가 될 사 api 요청
const [timer, setTimer] = useState<number>
const handleTimeUpdate = () => {
if (audioRef.current?.currentTime && audioRef.current.currentTime >= 3) {
setTimer((prev) => prev + 1);
}
};
if (timer === 10) {
console.log("api 작동");
}
- 위와 같이 작성했을 때, 일정 시간이 지난 후 “api 작동” 이라는 console이 찍혔음
- 즉 console로 찍는 부분을 api가 작동하도록 만들게 되면 문제 없이 실행 될 것임
4. custom hook으로 만들기
- Custom Hook 부분
import { useRef, useState } from "react";
export type UseAudioReturnType = [() => void, React.RefObject<HTMLAudioElement>];
function useAudio(): UseAudioReturnType {
const audioRef = useRef<HTMLAudioElement>(null);
const [timer, setTimer] = useState<number>(0);
const handleTimeUpdate = () => {
if (audioRef.current?.currentTime && audioRef.current.currentTime >= 3) {
setTimer((prev) => prev + 1);
}
};
if (timer === 10) {
console.log("api 작동");
}
return [handleTimeUpdate, audioRef];
}
export default useAudio;
- custom hook이 사용된 부분
import useAudio, { UseAudioReturnType } from "./hooks/useAudio";
function App() {
const [handleTimeUpdate, audioRef] : UseAudioReturnType = useAudio()
return (
<>
<div>
<audio
ref={audioRef}
controls
onTimeUpdate={handleTimeUpdate}
src="01-Copland-Danzon_Cubano-Bernstein1963.mp3"
></audio>
</div>
</>
);
}
export default App;
5. 알게 된 점
- 정말 다양하고 많은 event들이 존재하는 것을 알았고, audio에서도 event를 사용할 수 있다는 것을 알게 되었음
- 어떠한 특정 시간이 지난 후에 api를 실행하는 것은 개인적인 생각으로 setTimeout을 사용하면 될 것이라 생각하지만, audio가 재생된 후에 일정 시간이 지나면 api를 요청하는 것이 조금 어려울 것 같았다. 하지만 좋은 event를 많이 제공해 생각보다 쉽게 해결할 수 있었던 것 같다.
- 이전까진 custom hook을 사용해야 하는데 하면서 어렵다고 생각해 계속 미루고 있었다. 하지만 위와 같은 코드가 프로젝트 상 많은 곳에서 사용되기 때문에 무조건 custom hook을 만들어야 했고, 이전에 공부했던 custom hook을 다시 기억해내 어렵지 않게 구현한 것 같다. 코드를 구현하고 로직을 짤 때 처음부터 너무 어려울 것이라 생각해 막연하게 겁을 먹어 시간을 보내는 것 보다는 그런 시간에 로직을 조금이라도 더 생각하고 코드를 한 줄이라도 더 작성하는 것이 도움이 될 것 같다.
LIST
'Develop_story > trouble shooting' 카테고리의 다른 글
chat 역방향 무한 스크롤 비동기 처리 (0) | 2023.03.24 |
---|---|
Div에서 onClick event시 좌표 값 구하기 (0) | 2023.03.19 |
socket이 적용된 room에 들어갔을 때, 연결이 제대로 안 되는 상황 (0) | 2023.03.18 |
socket io join 중복 작동 (0) | 2023.03.18 |
채팅방 들어올 때 scroll 맨 밑으로 지정 (0) | 2023.03.18 |