슬라이더 밖에서 드래그를 끝내면 음악을 재생해도 슬라이더가 움직이지 않음
<Slider
aria-label="Volume"
value={currentTime}
onChange={handleSliderChange}
onChangeCommitted={handleSliderRelease}
onMouseDown={() => setIsDragging(true)} // 슬라이더를 드래그하기 시작하면 상태를 변경합니다.
onMouseUp={() => setIsDragging(false)} // 슬라이더에서 손을 떼면 상태를 변경합니다.
size="medium"
color="secondary"
max={musicData.duration}
/>
위와 같이 음악 재생 슬라이더를 onMouseDown
과 onMouseUp
옵션을 사용하여 현재 드래그 상태에 대한 여부를 상태로 관리하였는데 해당 옵션은 슬라이더 내부 영역에서만 마우스 상태를 인식하기 때문에 드래그를 하면서 슬라이더 밖으로 마우스가 나가게 되면 setIsDragging(false)
이 실행되지 않는다.
드래그상태는 슬라이더를 드래그하는 동안 슬라이더가 음악의 현재시간에 따라서 업데이트 되지 않도록 하기 위함이다.
<Slider
className="time-slider"
aria-label="Volume"
value={currentTime}
onChange={handleSliderChange}
onChangeCommitted={handleSliderRelease}
onMouseDown={() => setIsDragging(true)}
size="medium"
color="secondary"
max={musicData.duration}
/>
슬라이더의 onMouseUp
옵션을 제거
useEffect(() => {
// 마우스 업 이벤트를 전역적으로 처리
const handleMouseUpGlobal = () => {
setIsDragging(false); // 드래그 상태 업데이트
};
window.addEventListener('mouseup', handleMouseUpGlobal); // 전역에 마우스 업 이벤트 추가
return () => {
// 클린업 함수에서 이벤트 리스너 제거
window.removeEventListener('mouseup', handleMouseUpGlobal);
};
}, []);
mouseup
이벤트를 전역적으로 처리하도록 코드 추가하여 슬라이더 밖에서 mouseup
되어도 드래그 상태가 업데이트되어 문제가 해결되었다.
MUI Slider 컴포넌트의 onMouseUp
, onMouseDown
옵션은 해당 컴포넌트 영역 내부의 마우스 이벤트만 인식할 수 있다. 이러한 제한은 전역적으로 마우스 이벤트를 추가하여 해결할 수 있다.
음악페이지에 처음 접근했을 때 음악을 재생하면 음악은 정상적으로 나오지만 재생 슬라이더가 움직이지 않음
useEffect(() => {
const audioElement = audioRef.current;
if (audioElement) {
const handleTimeUpdate = () => {
// 슬라이더를 드래그 중이 아닐 때만 현재 재생 시간을 설정합니다.
if (!isDragging) {
setCurrentTime(audioElement.currentTime);
}
};
audioElement.addEventListener('timeupdate', handleTimeUpdate);
return () => {
audioElement.removeEventListener('timeupdate', handleTimeUpdate);
};
}
}, [audioRef, isDragging]);
audio
컴포넌트가 마운트 되면 audioRef
값이 업데이트 되는 줄 알고 audioRef
를 종속성 배열에 포함시켰지만 로그를 찍어 확인해보면 audioElement
값은 null
로 출력되었다.
useEffect(() => {
const audioElement = audioRef.current;
if (audioElement) {
const handleTimeUpdate = () => {
// 슬라이더를 드래그 중이 아닐 때만 현재 재생 시간을 설정합니다.
if (!isDragging) {
setCurrentTime(audioElement.currentTime);
}
};
audioElement.addEventListener('timeupdate', handleTimeUpdate);
return () => {
audioElement.removeEventListener('timeupdate', handleTimeUpdate);
};
}
}, [audioRef.current, isDragging]);
audioRef
를 종속성 배열에 넣으면, 참조 객체의 변화를 감지하는 것이 아니라 참조 자체를 나타내기 때문에 참조가 처음 생성될 때 한 번만 useEffect
가 실행된다.
하지만 audioRef.current
를 배열에 넣게 되면, 참조가 실제로 가리키는 값, 즉 오디오 엘리먼트가 실제로 DOM에 마운트되는 순간을 감지할 수 있게되어 audioElement
값이 null
이 아닌 실제 값으로 업데이트된다.
useRef
로 생성된 audioRef
객체는 참조 자체를 나타낸다.
때문에 컴포넌트의 생명주기 동안 안정적이고 변경되지 않아서 useEffect
의 종속성 배열에 넣으면 useEffect
는 한 번만 실행된다.
audioRef.current
는 참조가 현재 가리키고 있는 값이다.
이 값은 오디오 엘리먼트 자체를 가리키며, 컴포넌트가 렌더링되면서 오디오 엘리먼트가 DOM에 연결될 때 설정된다. 만약 오디오 컴포넌트가 처음 마운트될 때 null에서 실제 DOM 엘리먼트로 변경된다면, audioRef.current
값은 null
에서 참조가 가리키고 있는 엘리먼트 값으로 변하게 된다.