Inspired by this post, if we remove the Event Listener in cleanup after a delay does the previous reference of the Event Handler still gets attached to the browser?
Here is the code :
import React from "react";
import "./style.css";
// import React from "react";
// import "./style.css";
import { useState, useEffect,useRef } from 'react';
export default function App() {
const [userText, setUserText] = useState('');
// Any event handler (function in JS) declared with (){} will be a new
// object in every render. So for every render hanleUserKeyPress is assigned a
// new reference
const handleUserKeyPress = event => {
const { key, keyCode } = event;
if (keyCode === 32 || (keyCode >= 65 && keyCode <= 90)) {
// When this function is added as event listener to any browser activity
// The entire code gets snapshotted i.e for every activity userText would
// remain same.
// For any browser activity added to this tag it will see :
// const handleUserKeyPress = event => {
// const { key, keyCode } = event;
// if (keyCode === 32 || (keyCode >= 65 && keyCode <= 90)) {
// console.log('Value of userText : ' + '')//Added as snapshot
// console.log('Value of userText + key : ' + ''+key)
// setUserText(''+key);
// }
// };
console.log('Value of userText : ' + userText)
console.log('Value of userText + key : ' + userText+key)
setUserText(userText+key);
}
};
// This runs on every render(no dependency declared).
useEffect(() => {
window.addEventListener('keydown', handleUserKeyPress);
return () => {
// Add a delay to see
async function fun(){
await delay();
window.removeEventListener('keydown', handleUserKeyPress);
}
fun();
};
});
return (
<div>
<h1>Feel free to type!</h1>
<blockquote>{userText}</blockquote>
</div>
);
}
function delay(){
return new Promise(resolve =>{
setTimeout(()=> resolve(),5000)
})
}
So when initially the setup runs, React takes snapshot of the userText state inside handleUserKeyPress and is added to keydown event.
When a key is pressed(lets say ‘k’), setUserText is called and hence rendering of the component will take place with value (”+’k’ = ‘k’). After the code gets committed to the browser DOM, cleanup should run. But here, I am providing a delay of 5 seconds. During this time if I am pressing any key the previous version of the Event Handler is still added to keydown event. And hence any key(suppose ‘m’) that is pressed before 5 seconds gets over, would fire the handleUserKeyPress function with userText as ” and hence console should print ‘m’ and not ‘km’. Also userText should be set as ‘m’ rather than ‘km’.
Where I am getting it wrong?