Getting Closure with React

You,reacttypescriptjavascript

What's a closure?

Closures are like a backpack for functions. The backpack holds all of the values the function needs from its original environment, even if it's called in a different place. It gives functions access to all of its belongings no matter where it's called.

Here's a simple code example:

function createCounter() {
  let count = 0;
 
  return function () {
    count++;
    console.log(count);
  };
}
 
const counter = createCounter();
counter(); // Outputs: 1
counter(); // Outputs: 2
counter(); // Outputs: 3

The inner function has a closure (or backpack) that allows it to "remember" the value of count no matter where we call it!

This is a super powerful tool that makes a lot of things possible!

Closures in React

Here's the "React" version of the above code

export function Counter() {
  const [count, setCount] = useState(0);
 
  function updateCount() {
    setCount(count + 1);
  }
 
  return <button onClick={updateCount}>{count}</button>;
}

The closure is what allows updateCount to remember and access the value of count and the setCount function.

React Rendering - a snapshot of the component

export function Counter() {
  const [count, setCount] = useState(0);
 
  function updateCount() {
    setCount(count + 1);
    console.log(count); // what do we get here?
  }
 
  return <button onClick={updateCount}>{count}</button>;
}

Now what happens when we log the value of count after updating it?

It may surprise you - but it's still whatever the value was before you updated it! (i.e. 0 after first clicked)

The reason: React doesn't immediately update count so we are left with a stale value - in this case, what the count originally was before the update.

Instead, count (state) won't be updated until React renders the component again.

This is because state behaves like a snapshot