Stale Closures — I underestimated closures

Hello World 🌏

Few months back when I was working in React Class components, I’ve no idea what a stale closure is. Back then here is what I knew about closures:

A closure is a function with some preserved values. the values can be of outer scopes.

The closure is a function that can remember and modify variables from its lexical scope, regardless of execution scope.

Let’s understand closures by a real life analogy.

Suppose you have a magical camera 📷.

Photo by Keenan Constance on Unsplash

The magic is of the camera 📷 is that, any photo 🤳 you take, you can interact with the photo.

Example: You took a photo of a lion 🦁,

Now you have the power
1. to open up the photo and interact with the lion 🦁,
2. you can touch 👆 the lion regardless of your place 🌏 either be in your home 🏠, your grannys home 🏡 or on moon 🌙 .
3. if you apply some filters to the photo, the same filter will get applied to the lion 🐯. Meaning both photo and the lion are connected.

As far as you have your magical camera 📷 you can interact 👆 with the lion 🦁.

Similarly in JavaScript, a function is a magical camera,

If you use a variable which is outside the scope of current function, the snapshot of the variable will be taken.

And the snapshot is not static, just like of the picture of lion. If the value of variable changes, you’ve access to the updated value. Just like you can apply filters to lion, you can update the value of the outside variable.

Consider following code snippet:

In the above example, count is captured by the returned function from numberOfYug . As you can see I can read and modify the value.

Let us take another example of async, where I will be calling incrementYug and still count variable will be increased by factor of 1.

Now it is pretty much clear that, closure works regardless of there place, and the variables can be accessed outside their execution context.

We can check, if any function has a closure variables or not. Simple do console.dir(functionName) .

This was all about closures, now let me explain what I missed to learn about closures.

So this was my understanding about closures.

When moved to functional component in React then I started getting old values while working with hooks and specially timers. Firstly I though it is the problem of React but later learned that this is not a problem. This is how closures work. And I was expericencing the situation called Stale Closure.

Basically a stale closure is a function which is preserving an old value of a variable.

The is may occur due to two reasons:
1. Any other function updated a value in which closed over variable is dependent.
2. The function which is holding closure function (parent) is done executing, while the closure is still hold the old value.

Lets consider below code, which is demonstrating Reason 1:

Can you guess what will be printed in console?

.

.

.
In the console Current Yug is 0 will be printed.
How? Due to stale closures.

printYug is holding message . And value of message is dependent on count .

count is updated by another function incrementYug .

Let’s do a console.dir on logYug to see what exactly it is holding after calling increaseYug 3 times.

As you can see, the logYug (printYug) is preserving old values.

So for this problem we have two solution:

1. Change const message to let message and on every incrementYug update the message.

2. Move the message const inside printYug.

Now let us see the second reason due to which stale closure condition might occur. The second reason is:
The function which is holding closure function (parent) is done executing, while the closure is still hold the old value.

Consider following code snippet and can you guess what will be printed in console?

.

.

In the console current Yug is 1 will be printed.

The function (incrementYug) which is holding closure function (printYug) is done executing, while we are still keeping the reference of closure function (printYug) which is still holding the old value and still using it.

Here printYug is creating two closures. One with message and one with count.

In above code every execution of `incrementYug` is returning new instance of printYug but we are keeping old instance and using it.

For this problem we have two solution:

1. Finding and Using the fresh instance of closure function (This is done by React in case of hooks)

2. Use count directly inside printYug .

I hope my experience with closure make you learn something new about closures.

--

--

--

A passionate iOS Developer since 2014.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

React Router Setup

Phase 2 Project -ClimateSite

An Easy to Understand Visual Guide for JavaScript Promises methods

Dynamically Importing Modules in JavaScript

How to Know When to Use Redux

Strongly Keyed Maps in TypeScript

React Query in Web Extensions

Integrating Nuxt Into a Build Pipeline

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
राहुल मिश्रा

राहुल मिश्रा

A passionate iOS Developer since 2014.

More from Medium

🚀 Getting Started to use Styled Components in your React App

Top 5 ReactJS UI Component Libraries

Chapter 11: CSS Colors in RGB and HSL

Typescript vs. Javascript: The Key Differences You Should Know in 2022

TypeScript vs. JavaScript: The Key Differences You Should Know — Flatlogic Blog