A Conversation About Memory Leaks Every Junior Dev Should Read

Wed Dec 03 2025

react logo


"Bro… the app is again slowing down after 5–6 minutes of running," Rahul whispered like he just broke production.

Sitting across the desk, sipping coffee like a monk who has seen 1000 deploys fail, was our senior engineer, Arvind. He didn't panic. He didn't even blink.

He just asked, "Okay Rahul… show me the code."

Rahul opened his React app.

Arvind stared at the screen. And then he smiled that dangerous senior-dev smile - the one that says "You fool… but don't worry, I shall enlighten you."

"Rahul… you have created a memory leak."

Rahul blinked. "A what?"

"Memory leak," Arvind said. "Think of it like this: your program keeps reserving seats in a movie theater but never frees them. Eventually, no seats left… and your app just dies."


Leak #1: Event Listeners That Never Die

Rahul's Component:

useEffect(() => {
  window.addEventListener("resize", () => {
    console.log("resized");
  });
}, []);

Arvind laughed."Rahul… where is the cleanup?"

Rahul stared."What cleanup?"

Arvind rewrote it:

useEffect(() => {
  const handler = () => console.log("resized");
  window.addEventListener("resize", handler);

  return () => {
    window.removeEventListener("resize", handler);
  };
}, []);

"See?" Arvind said."Always clean up what you set up. Listeners, intervals, sockets, subscriptions… everything. Otherwise JS will keep them forever like your ex who keeps your hoodie."


Leak #2: setInterval → setINFINITE problem

Rahul had this:

useEffect(() => {
  setInterval(() => {
    console.log("running...");
  }, 1000);
}, []);

"No cleanup??" Arvind shouted dramatically.

Correct version:

useEffect(() => {
  const id = setInterval(() => {
    console.log("running...");
  }, 1000);

  return () => clearInterval(id);
}, []);

Leak #3: Storing giant objects in state 'just because'

Rahul's code had:

const [data, setData] = useState(hugeObject);

Arvind looked at him and said, "Bro… did you just store a 30MB JSON response in state? What are you… an S3 bucket?"

Correct approach:

const [items, setItems] = useState(hugeObject.items.slice(0, 50));

Or even better - store only what you need.


Leak #4: Never cancelling API calls

Rahul wrote:

useEffect(() => {
  fetch("/api/products")
    .then((res) => res.json())
    .then(setProducts);
}, []);

Arvind shook his head.

"Imagine the user leaves the page before the fetch finishes. The response still comes… but the component is gone. React gets confused and logs warnings."

Correct version (AbortController):

useEffect(() => {
  const controller = new AbortController();

  fetch("/api/products", { signal: controller.signal })
    .then((res) => res.json())
    .then(setProducts)
    .catch((err) => {
      if (err.name !== "AbortError") console.error(err);
    });

  return () => controller.abort();
}, []);

Rahul: "So I have to tell the API to chill when I leave?" Arvind:  "Exactly. Tell it to stop shouting into the void."


Leak #5: Keeping references alive by accident

Rahul had this debounced function outside the effect:

const debounced = debounce(() => {
  console.log("typing...");
}, 500);

useEffect(() => {
  inputRef.current.addEventListener("input", debounced);
}, []);

Arvind sighed,  "This debounced function will never die. Ever. Because some part of your component still holds on to it."

Correct approach:

useEffect(() => {
  const handler = debounce(() => {
    console.log("typing...");
  }, 500);

  const input = inputRef.current;
  input.addEventListener("input", handler);

  return () => {
    input.removeEventListener("input", handler);
    handler.cancel();
  };
}, []);

"Create functions inside the effect," Arvind explained. "If you create them outside, React doesn't know when to clean them."


Before leaving for lunch, Arvind gave Rahul the golden rule: "Every time you open something, ask yourself: who will close it?"

Listeners? Close them.

Intervals? Clear them.

APIs? Abort them.

Subscriptions? Unsubscribe them.

Coding is like cleaning your room - if you don't do the small cleanups daily, one day you'll find an empty pizza box from 2021 under your chair.

Wed Dec 03 2025

Help & Information

Frequently Asked Questions

A quick overview of what Apptastic Coder is about, how the site works, and how you can get the most value from the content, tools, and job listings shared here.

Apptastic Coder is a developer-focused site where I share tutorials, tools, and resources around AI, web development, automation, and side projects. It’s a mix of technical deep-dives, practical how-to guides, and curated links that can help you build real-world projects faster.

Cookie Preferences

Choose which cookies to allow. You can change this anytime.

Required for core features like navigation and security.

Remember settings such as theme or language.

Help us understand usage to improve the site.

Measure ads or affiliate attributions (if used).

Read our Cookie Policy for details.