Become a member
to unlock all features

Level Up!

Access all courses & lessons on egghead today and lock-in your price for life.


    Understanding setState in componentDidMount to Measure Elements Without Transient UI State


    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.



    Become a Member to view code

    You must be a Pro Member to view code

    Access all courses and lessons, track your progress, gain confidence and expertise.

    Become a Member
    and unlock code for this lesson
    orLog In




    Instructor: 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.

    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.

    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.

    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.

    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.

    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.

    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.

    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.