Getting closure with React

If you've got any questions feel free to DM on Twitter @reillyjodonnell
Search for a command to run...

If you've got any questions feel free to DM on Twitter @reillyjodonnell
No comments yet. Be the first to comment.
Someone shared this image above. At first glance, I wasn’t sure about the perf implications — so let’s break it down from first principles :D Let’s deconstruct this monster Here’s the code: // Function to flatten React Context Providers. const flatte...

Intro Hello it’s me from the future! I originally was going to go over file based routing but pivoted to going over important SSR concepts with React / how Bun makes it easy. It’s full of struggles with hydration (mismatches), React entry points, and...

history? Serverless is EVERYWHERE and for good reason: nearly infinite scalability, physically closer to users, and pay-for-what-you-use pricing. But not without tradeoffs — vendor lock-in, (potentially) higher costs, and the infamous cold-starts. cf...

Powered by bash and AppleScript!

Sockets can only transmit binary (text.) Imagine we have this data const message = {id: '123', name: 'Reilly', message: 'Hey'} Here's the problem: we want to send this data to the ui but we have hundreds of useEffects spread throughout the codebase....

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!
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.
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](https://react.dev/learn/state-as-a-snapshot)