I am a student studying react.
There's a problem with the component I'm making right now.
What I am trying to make is a scroll-type picker similar to the link below.
https://codepen.io/gnauhca/pen/JrdpZZ
In the process of implementing this, there is a problem in registering and removing eventListener in eventListener.
import { useState, useRef, useEffect } from "react";
function Scroller() {
const array = [170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180];
const [dragEventHistory, setDragEventHistory] = useState([]);
const [dragEventStart, setDragEventStart] = useState(null);
const scrollerContainer = useRef();
const scrollerList = useRef();
useEffect(() => {
const moveList = (clientY) => {
const difference = Number(dragEventStart) - Number(clientY);
scrollerList.current.style.transform = `translate3d(0, -${difference}px, 0)`;
};
const onMouseMoveEventHandler = (e) => {
console.log(e);
e.preventDefault();
moveList(e.clientY);
};
const onMouseDownEventHandler = (e) => {
console.log(e);
e.preventDefault();
setDragEventStart(e.clientY);
scrollerContainer.current.addEventListener(
"mousemove",
onMouseMoveEventHandler
);
};
const onMouseUpEventHandler = (e) => {
console.log(e);
e.preventDefault();
scrollerContainer.current.removeEventListener(
"mousemove",
onMouseMoveEventHandler
);
};
scrollerContainer.current.addEventListener(
"mousedown",
onMouseDownEventHandler
);
scrollerContainer.current.addEventListener(
"mouseup",
onMouseUpEventHandler
);
return () => {
scrollerContainer.current.removeEventListener(
"mousedown",
onMouseDownEventHandler
);
scrollerContainer.current.removeEventListener(
"mouseup",
onMouseUpEventHandler
);
};
}, []);
return (
<div
className="scroller-container"
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
overflow: "hidden",
width: 200,
height: 250,
}}
ref={scrollerContainer}
// onTouchStart={onTouchStartEventHandler}
// onTouchEnd={onTouchEndEventHandler}
>
<ul className="scroller-list" ref={scrollerList}>
{array.map((item, index) => {
return (
<li
key={index}
style={{
width: 200,
height: 50,
display: "flex",
justifyContent: "center",
alignItems: "center",
backgroundColor: "orange",
fontSize: 30,
}}
>
{item}
</li>
);
})}
</ul>
</div>
);
}
export default Scroller;
If I define functions without using useEffect, depending on the change of 'dragEventStart' state, the callback function registered as an event cannot be removed in the process of component rerendering.
If I define functions in useEffect, removeEventListener function can point the callback function that is same with addEventListener function's callback. But dragEventStart state can't be changed. However, if dragEventStart is included in the dependency of useEffect, it becomes the same as when useEffect is not used.
How can I solve this problem? I need help!!