๐จ TroubleShotting
๋๋๊ทธ๋ฅผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ด mouseEvent๋ก ๊ตฌํํด๋ณด๊ณ ์๋ ์ค,
๋๋๊ทธ๋ฅผ ๋ฐ๋ณต์ ์ผ๋ก ํ๋ฉด ์ด์ ์ ๋ง์ง๋ง์ผ๋ก ๋๋๊ทธ ํ๋ ์์์์ ๋ ๋๋๊ทธ ๋์ง ์๊ณ
์๊พธ ์ฒ์์ผ๋ก ๋์๊ฐ๋ ํ์์ด ๋ฐ์ํ๋ค.
์ด๋ฐ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
๋ฌธ์ ๋ฐ์์ ๋ฐฐ๊ฒฝ - As Is
const [startMoveX, setStartMoveX] = useState(0);
const [mouseDown, setMouseDown] = useState(false);
const [movingX, setMovingX] = useState(0);
const handleMouseDown = (clickEvent: React.MouseEvent<Element, MouseEvent>) => {
setMouseDown(true);
setStartMoveX(clickEvent.screenX);
};
const handleMouseUp = (mouseUpEvent: React.MouseEvent<Element, MouseEvent>) => {
setMouseDown(false);
};
const handleMouseMove = (moveEvent: React.MouseEvent<Element, MouseEvent>) => {
setMovingX(moveEvent.screenX);
};
return (
<div className="w-full overflow-hidden" ref={containerRef}>
<div
className="flex flex-nowrap gap-4 h-[300px] w-max overflow-x-visible"
onMouseDown={handleMouseDown}
onMouseUp={handleMouseUp}
onMouseMove={ handleMouseMove }
style={{
transform: `translateX(${mouseDown ? movingX - startMoveX : null}px)`
}}
mouseDown ๋์์ ๋์ ์์น๋ฅผ startMoveX๋ผ๋ state๋ก ๊ด๋ฆฌํ๊ณ
mouseMove ์ค์ ์์น๋ฅผ movingX๋ผ๋ state๋ก ๊ด๋ฆฌํ ๋ค,
movingX - startMoveX ๊ฐ์ ์ด๋๊ฑฐ๋ฆฌ๋ผ ํ๋จํ์ฌ style์ ์ด๋๊ฑฐ๋ฆฌ๋งํผ translateX๋ก ์ ์ฉํ๋ค.
Why(์ด์ ) ?
๋๋๊ทธ๋ ๋งค ํ๋ ์๋ง๋ค ์์ ์ด๋์ด ๋ชจ์ฌ์ ๊ตฌํ๋๋ค.
์ฆ [---] ์ด๊ฒ ํ ํ๋ ์์ด๋ผ๊ณ ํ๋ฉด, [ ์์ ์์ํด์ --- ๋งํผ ์ด๋ํ๊ณ ] ๊ฐ ๋์ด์ผ ํ ํ๋ ์์ด ๋๋๋ค.
์ด๋ฐ ํ๋ ์๋ค์ด ๋ชจ์ฌ์ ํ ๋ฒ์ ๋๋๊ทธ๊ฐ ๋ฐ์ํ๋ค.
์ฐ์ handleMouseMove ํจ์ ๋ด์ ์ด๋๊ฑฐ๋ฆฌ๋ฅผ ๊ฐฑ์ ํ๋ ๋ก์ง์ ์ค์ง mouseDown์ด true ์ผ ๋๋ง ์คํ๋์ด์ผ ํ๊ณ
1. ์ด๋๊ฑฐ๋ฆฌ๋ ๋์ ๋์ด์ผ ํ๋ค.
์ด๋๊ฑฐ๋ฆฌ๊ฐ ๋์ ๋์ด์ผ ํ๋ ์๋ค์ด ๋ชจ์ฌ์ ํ ๋ฒ ๋๋๊ทธ์ ์ด ์ด๋๊ฑฐ๋ฆฌ๊ฐ ๋์จ๋ค.
๋์ ๋์ง ์์ผ๋ฉด ์ ์ผ ๋ง์ง๋ง ํ๋ ์์์์ ์ด๋๊ฑฐ๋ฆฌ๋ง ์ธก์ ์ด ๋์ด ์๊พธ ์์ ์ผ๋ก ๋์๊ฐ๋ฒ๋ ธ๋ ๊ฒ์ด๋ค.
๋์ ๋๋ ๊ฐ์ ๊ณ์ ๋ณํ๋ ๊ฐ์ด๋ฏ๋ก position์ด๋ผ๋ state๋ฅผ ์๋ก ๋ง๋ค์๊ณ , handleMouseMove ํจ์๋ฅผ ์ด๋ ๊ฒ ๋ฐ๊ฟจ๋ค.
์ํ์ฐฉ์ค 1
const [position, setPosition] = useState(0);
...
const handleMouseMove = (moveEvent: React.MouseEvent<Element, MouseEvent>) => {
if(mouseDown) {
setMovingX(moveEvent.screenX);
setPosition((prev) => prev + (movingX - startMoveX));
}
};
return (
<div className="w-full overflow-hidden" ref={containerRef}>
<div
className="flex flex-nowrap gap-4 h-[300px] w-max overflow-x-visible"
onMouseDown={handleMouseDown}
onMouseUp={handleMouseUp}
onMouseMove={handleMouseMove}
style={{
transform: `translateX(${mouseDown ? position : null}px)`
}}
>
...
๊ทผ๋ฐใ
ใ
ใ
์ด๋ ๊ฒ ๋ฐ๊ฟจ๋๋ ์กฐ๊ธ๋ง ๋๋๊ทธ๋ฅผ ํด๋ ์์ฒญ๋๊ฒ ์ด๋ํด๋ฒ๋ ธ๋ค.
console.log(position)์ ํ๋๋ 3519 ๋ผ๋ ์ซ์๊ฐ ๋์๋ค.
์ค์ ๋ก๋ ํ 50px ํ ๊ฒ ๊ฐ์๋ฐ..
2. ์์์ (startMoveX)
์ด๋๊ฑฐ๋ฆฌ๋ฅผ movingX - startMoveX๋ก ํด๋์๋๋ฐ,
startMoveX๋ mouse๊ฐ ์๋ฌด๋ฆฌ ์์ง์ฌ๋ ๊ณ์ ์ฒ์ ํด๋ฆญํ ๊ณณ์ด์ง ์์๊ฐ?
๊ทธ๋ฌ๋, ๋ง์ฐ์ค๋ฅผ ๋ง์ด ์์ง์ด๋ฉด ์์ง์ผ์๋ก movingX - startMoveX๊ฐ ๊ณ์ ๋์ด๋ฌ๊ณ ๊ทธ๊ฒ ๋์ ์ด ๋์ด 3519 ๋ผ๋ ์ด๋งํ ์ซ์๊ฐ ๋์๋ ๊ฒ์ด๋ค.
startMoveX๋ฅผ ๋ง์ฐ์ค๊ฐ ์์ง์ผ ๋๋ง๋ค ๊ฐฑ์ ํด์ค์ผ๊ฒ ๋ค!
ํ์ฌ handleMouseMove์ setStartMoveX() ๋ก์ง์ ์ถ๊ฐํ๋ค.
์ํ์ฐฉ์ค 2
const handleMouseMove = (moveEvent: React.MouseEvent<Element, MouseEvent>) => {
if (mouseDown) {
setMovingX(moveEvent.screenX);
setStartMoveX(moveEvent.screenX);
setPosition((prev) => prev + (movingX - startMoveX));
}
};
๊ทผ๋ฐ ๋ ์ด๋ฌ๋๋, ์ด๋ฒ์๋ ๋ด๊ฐ ์์ง์ธ ๋งํผ๋ง ์ด๋ํ๋๋ฐ ๋๊ฒจ์ ๋ก ๋ก ๋๋๊ทธ๊ฐ ๋๋ ๊ฒ ์๋๊ฐ..
์๋ ์ด๋ ๊ฒ ๋ปฃ๋ปฃํ ๋๋๊ทธ๋ฅผ ์ํ ๊ฒ ์๋์๋๋ฐ...
3. ๋ง์ฐ์ค ์์ง์๊ณผ ๋์์ ์ด๋๊ฑฐ๋ฆฌ ๊ฐฑ์
setMovingX๋ฅผ ํ ๋ค์ -> ์ด๋๊ฑฐ๋ฆฌ๊ฐ ๊ฐฑ์ ์ด ๋๋ ๋น์ฐํ ๊ฒฐ๊ณผ์๋ค.
์ฆ, ๋ง์ฐ์ค๊ฐ ์์ง์ด๋ ๋์์ ์ด๋๊ฑฐ๋ฆฌ๊ฐ ๊ฐฑ์ ์ด ๋๋ ๊ฒ ์๋๋ผ,
์์ง์ด๊ณ ๊ทธ๊ฑธ setMovingX๋ฅผ ํ ๋ค์ re-๋ ๋๋ง์ด ๋ ํ ๊ณ์ฐ๋ ๊ฒฐ๊ณผ๋ฌผ์ด ๋ณด์ฌ์ก๋ ๊ฒ.
๊ทธ๋์ movingX state๋ฅผ ์์ด๋ค. ๊ทธ๋ฅ ๋ฐ๋ก moveEvent.screenX์์ startMoveX๋ฅผ ๋บ๋ค.
์ํ์ฐฉ์ค 3
const handleMouseMove = (moveEvent: React.MouseEvent<Element, MouseEvent>) => {
if (mouseDown) {
const deltaX = moveEvent.screenX - startMoveX;
setPosition((prev) => prev + deltaX); // ์ด์ ์์น์ ์ด๋ ๊ฑฐ๋ฆฌ๋ฅผ ๋ํจ
setStartMoveX(moveEvent.screenX);
}
};
what(๊ฒฐ๊ณผ) - To Be
์ด์ ์ฒ๋ผ ๋๋๊ทธ๋ฅผ ํ๊ณ ๋ค์ ๋๋๊ทธ๋ฅผ ํ ๋ ์์ ์ผ๋ก ๋์๊ฐ์ง ์๊ณ
๋ง์ง๋ง ๋๋๊ทธ์์ ์ด์ด์ ๋๋๊ทธ๋ฅผ ํ ์ ์๋๋ก ์ฑ๊ณตํ๋ค.
๐ก ์๋กญ๊ฒ ์๊ฒ๋ ์
๋๋๊ทธ์ ์๋์๋ฆฌ: ์์ ํ๋ ์๋ค์ ๋ชจ์