I have a fairly simple case, I didn't think it would cause me problems. If Shift key is pressed I want to add a e.preventDefault() to my selectstart DOM event using React. Inoticed that the problem is that the isShiftDown doesn't update correctly. I don't understand why this is happening.
The isShiftDown isnside handleSelectStart function in Paragraph component is always false.
The same value inside App component toggle correctly.
All I have to do is prevent text selecting inside Paragraph if Shift is pressed. StackBlitz example may seem strange, but my real case much more expanded.
// Paragraph
const Paragraph = ({ isShiftDown }) => {
let paragraphRef;
const handleSelectStart = e => {
console.log('Paragraph => handleSelectStart => isShiftDown =', isShiftDown);
if (isShiftDown) {
e.preventDefault();
}
};
React.useEffect(() => {
paragraphRef.addEventListener('selectstart', handleSelectStart, false);
return () => {
paragraphRef.removeEventListener('selectstart', handleSelectStart);
};
}, []);
return (
<p ref={e => (paragraphRef = e)}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
);
};
// App
const App = () => {
const [isShiftDown, setIsShiftDown] = React.useState(false);
const handleKeyUp = e => {
if (e.key === 'Shift' && isShiftDown) {
setIsShiftDown(false);
}
};
const handleKeyDown = e => {
if (e.key === 'Shift' && !isShiftDown) {
setIsShiftDown(true);
}
};
React.useEffect(() => {
document.addEventListener('keyup', handleKeyUp, false);
document.addEventListener('keydown', handleKeyDown, false);
return () => {
document.removeEventListener('keyup', handleKeyUp, false);
document.removeEventListener('keydown', handleKeyDown, false);
};
}, []);
return (
<div className="App">
<Paragraph isShiftDown={isShiftDown} />
</div>
);
};
ReactDOM.render(
<App />,
document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>