Answer the question
In order to leave comments, you need to log in
Drag'n'drop - why is the old state displayed in useEffect?
The bottom line: when the onMouseDown event occurs on the div('area') of the child component, motion.active : true and then the mousemove and mouseup listeners are launched, where mousup resets motion.active : false. But! After releasing the mouse button and changing its position, mousedown fires (I don’t understand how) again and sets motion.active : true and everything starts over again, which should not be.
function App() {
const [motion, setMotion] = React.useState({
active: false,
i: null,
stX: null,
movX: null,
movY: null
})
const handleMouseDown = (e, index) => {
e.preventDefault()
const parent = e.target.parentNode.getBoundingClientRect();
const element = e.target.getBoundingClientRect();
const x = element.left - parent.left;
const y = element.top - parent.top;
setMotion({
...motion,
active: true,
i: index,
stX: x
})
}
React.useEffect(()=>{
window.addEventListener('mousemove', handleMouseMove);
window.addEventListener('mouseup', handleMouseUp);
},[handleMouseDown])
const handleMouseMove = (e) => {
if(motion.active) setMotion({
...motion,
movX: e.offsetX,
movY: e.offsetY
})
}
const handleMouseUp = () => {
setMotion({
active: false,
})
}
return (
<div className="App">
<Panel />
<Search />
<h3>{`${motion.active}__${motion.movX}++${motion.stX}`}</h3>
<div
className="wrapper"
>
{state && state.map((item, index)=>
<div
className="area"
onMouseDown={(e)=>handleMouseDown(e, index)}>
<MiniItem
key={item._id}
flag={flag}
resetStateHidden={resetStateHidden}
setFlag={setFlag}
item={item}
index ={index}
state={state}
motion={motion}
/>
</div>
)}
</div>
</div>
);
}
Answer the question
In order to leave comments, you need to log in
Having practically brought himself to an existential crisis, he found a solution. I'll leave it in case anyone encounters state loss due to an event listener inside the useEffect hook.
React.useEffect(()=>{
// добавление слушателя на все окно
window.addEventListener('mousemove', mouseMove);
window.addEventListener('mouseup', mouseUp);
return () => {
// удаление слушателя после обновления эффекта
window.removeEventListener('mousemove', mouseMove);
window.removeEventListener('mouseup', mouseUp);
}
}
)
// эвент движения
const mouseMove = (e) => {
if(motion.active){
// считаем дельту положения мышки в моменте и первоначального положения
const delta = e.pageY - motion.stY;
setMotion(motion=>(
{
...motion,
y: delta
}
)
)
}
}
// эвент отпускания клавиши и конец днд
const mouseUp = () =>{
setMotion(motion=>(
{
...motion,
i: null,
active: false,
y: 0,
})
)
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question