🚀 𝑭𝒓𝒐𝒏𝒕𝒆𝒏𝒅 𝑰𝒏𝒕𝒆𝒓𝒗𝒊𝒆𝒘 𝑸𝒖𝒆𝒔𝒕𝒊𝒐𝒏 Here’s 👇 a React interview question that even senior developers sometimes get wrong A simple React component with a button ⏺️ and a counter ⏲️ state. Could you identify the problems with this component and explain what the console output will be? There is also a popular term in React/Frontend engineering for this kind of issue. Write your answer in the comments 📄 along with your thoughts. Follow-up questions: 1️⃣ Will the output change if we clean up the event listeners that are attached? 2️⃣ Since we are attaching click handlers to both the button and the whole document, what will be the order of propagation here? Which handler will execute first if we click the button? 3️⃣ Will the output change if we update the state like this? 𝒔𝒆𝒕𝑪𝒐𝒖𝒏𝒕𝒆𝒓((𝒄𝒐𝒖𝒏𝒕) => 𝒄𝒐𝒖𝒏𝒕 + 1) ~ Aslam Mohammed 🇮🇳 #ReactJS #FrontendDevelopment #JavaScript #WebDevelopment #FrontendInterview #CodingInterview
Small follow-up insight ✨ Many developers fix this by adding counter to the dependency array like how I did in the interview and posted in the comment. But in real apps, constantly re-attaching event listeners can become inefficient. Another approach is using useRef to keep the latest value without re-registering the listener (image attached 👇 ):
The useEffect runs only once because the dependency array is empty. During the first render, it attaches a document click event listener that captures the initial value of counter which is 0 due to JavaScript closure. Every time we click anywhere on the page (inside or outside the button), the browser triggers that same event listener, so console.log executes each time. However, since the listener captured the initial state, it always prints 0. If we include counter in the dependency array, the effect will run again whenever counter changes. Without a cleanup function, this would create multiple event listeners, causing multiple logs for a single click. To avoid this, we should return a cleanup function to remove the previous listener.
First, this code is messy—not suitable for an interview. Second, it has several issues: 1. The useEffect adds a global click listener with an empty dependency array, creating a stale closure. The listener captures the initial counter value (0) and never updates, so every click logs Counter is: 0 regardless of how many times the button is pressed. 2. The event listener is never cleaned up. If the component unmounts, the listener remains, causing memory leaks. You must return a cleanup function from useEffect to remove it. 3. The onClick handler uses an inline arrow function, which creates a new reference on every render. Latest: why complicating things you just want to log when clicked use a handler with set state and log inside. Make things easy
Hello bhaiya, it would be great if you could share your interview experience here: https://l0ser.vercel.app/ so that juniors can learn and be motivated.
Hint 💡: The issue is related to how 𝐜𝐥𝐨𝐬𝐮𝐫𝐞𝐬 𝐛𝐞𝐡𝐚𝐯𝐞 𝐰𝐢𝐭𝐡 𝐞𝐯𝐞𝐧𝐭 𝐥𝐢𝐬𝐭𝐞𝐧𝐞𝐫𝐬 𝐢𝐧 𝐑𝐞𝐚𝐜𝐭.