Understanding setState in componentDidMount to Measure Elements Without Transient UI State

Jason Brown
InstructorJason Brown
Share this video with your friends

Social Share Links

Send Tweet
Published 6 years ago
Updated 5 years ago

In this lesson we'll explore using setState to synchronously update in componentDidMount. This allows for us to use getBoundingClientRect or other synchronous UI calls and make changes to the UI without a transient UI state.

Instructor: [00:00] React will allow you to do a setState and componentDidMount without adding a transient UI. We can demonstrate this by first adding a ref to our h2. This gives us access to the raw DOM node of the h2. In our componentDidMount, we can call this.r.getBoundingClientRect. This will get the dimensions of the h2, which is a block-level element. We can look and see that the dimensions of this h2 are 591 by 28.

[00:55] With this call, this will get the width/height and the left/right positions of our element, but all we care about is the width and the height, which we will de-structure. Then we can do a this.setState of width and height.

[01:17] We can see that it instantly updated to our 591 by 28. What we didn't see is a zero by zero. Even though we did a setState in componentDidMount, this was after the layout phase. The DOM exists, but it has not yet been painted onscreen, so the user doesn't actually see anything.

[01:41] What that means is we can do synchronous setStates like getting dimensions of something and adjusting them and it won't cause any jank for the user. This also holds true for componentDidUpdate.

[01:57] If we were to add some sort of asynchronicity into here, like, say, a setTimeout -- put it at zero and then call that -- if we refresh, you can see that there was a quick flash from zero to the numbers.

[02:21] We can see that even at the quickest asynchronicity that we will see a flash of a transient UI state of zero by zero, but when we are completely synchronous, there's no flash.

[02:35] One thing to note about this is that Render will be called twice, rather than just once. Take that into consideration of your performance necessities. We can prove that by doing a console.countRender. This will count how many times our Render is called.

[02:57] If we save that, open up, and refresh, we can see that it was called twice and then it appeared onscreen. Yes, Render is being called twice. However, we are only showing one state and not a transient UI state.

egghead
egghead
~ 7 minutes ago

Member comments are a way for members to communicate, interact, and ask questions about a lesson.

The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on egghead.io

Be on-Topic

Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at support@egghead.io.

Avoid meta-discussion

  • This was great!
  • This was horrible!
  • I didn't like this because it didn't match my skill level.
  • +1 It will likely be deleted as spam.

Code Problems?

Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context

Details and Context

Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!

Markdown supported.
Become a member to join the discussionEnroll Today