A React Hooks Challenge for Senior React Developers | by bytefish | May, 2022

Are you able to remedy this downside?

Some time in the past, a buddy despatched me a React demo to check my understanding of React.

I took a more in-depth have a look at this demo. Though the code may be very small, it accommodates the next:

  • Closure downside with hooks
  • The precept of state

That is certainly an attention-grabbing problem. Right here I need to share this problem with you. After studying this text, you’ll have a deeper understanding of useful elements.

The demo’s construction is easy: it accommodates a button and a listing.

And when the button is clicked, it provides one thing to the checklist, as you’ll be able to see beneath:

It seems like this:

Till now, it’s fairly easy, isn’t it?

The humorous and complicated half is that if you click on the Add button, it should add a brand new button that additionally has a onClick=add occasion to the checklist.

So, when you click on Add seven occasions, the web page will appear like this:

add button with seven buttons numbered from zero to six

Do you get it? Right here is a web-based demo:

Here’s a query: if we click on these numbers, what is going to occur?

  • If we click on button 0 , what is going to the checklist appear like?
  • If we click on button 6 , what is going to the checklist appear like?

You’ll be able to suppose and follow by yourself earlier than studying the remaining half.

Some builders might imagine a brand new button will likely be pushed to the checklist after clicking a quantity.

However this reply is mistaken. Once we click on on a quantity, the size of the checklist will change into [the number + 1], and the final quantity within the checklist will change into[the largest number before the click + 1].

I do know this assertion is a little bit of a mouthful, however let me clarify with just a few examples.

Suppose the present checklist is that this:

add button with seven buttons numbered from zero to six

If we click on 0 , the size of the checklist will change to 0 + 1 = 1 , and the final quantity will change into 6 + 1 = 7 .

Now, if we click on 2, the size of the checklist will change to 2 + 1 = 3, and the final quantity will change into 6 + 1 = 7 .

add button next to three buttons: zero, one, and seven

You can provide it a strive by offering an embedded demo.

However have you learnt why this phenomenon happens?

That is the results of two elements working collectively:

  • The closure downside with hooks
  • How the state is assembled

Let’s have a look at the add perform:

When a button was clicked, the add perform was referred to as. After which, the closure will likely be created based mostly on its context.

The closure accommodates:

And checklist and setList had been created by useState hooks.

Here’s a widespread misunderstanding: The checklist returned by a number of calls to useState is similar object with the identical tackle in reminiscence.

In reality, the checklist returned by every name to useState is calculated based mostly on the next formulation:

base state + update1 + update2 + … = present state

So, the checklist returned by a number of calls to useState are completely different objects with completely different addresses in reminiscence.

This results in a vital phenomenon: the add capabilities corresponding to every quantity are in several closures, and their checklist has completely different values.

i is a module-level variable; they’re the identical one in every closure.

Whenever you click on 0 , the next occurs:

  • i is a module-level variable, 6
  • checklist on this closure is []

So it truly executes the folllowing:

setList(
[].concat(
<button key=7 onClick=add>7</button>
)
);

So the checklist on the webpage turns into [7] .

Whenever you click on 2 , this occurs:

  • i is a module-level variable, 6
  • checklist on this closure is [0, 1]

So it truly executes this:

setList(
[0, 1].concat(
<button key=7 onClick=add>7</button>
)
);

And the checklist on the webpage turns into [0, 1, 7] .

Do you get it?

Because the meeting precept of the state is:

base state + update1 + update2 + … = present state

So every time useState is named, its return values are completely different objects.

And due to the closure, completely different checklist values are recorded on every quantity button.

This finally results in the phenomenon described at the start of the article.

I hope this text is beneficial to you.

In the event you don’t need this closure phenomenon, you’ll be able to modify the parameter of setList to perform type.

More Posts