When State Changes React Does Render Again

When does React re-return components?

React re-render explained

React is known for providing a fast user experience past just updating the parts of the UI that have changed.

When looking into React's render performance, there are a few terms and concepts that tin can be hard to understand. It wasn't 100% clear to me what a VDOM was or how React decides to re-render components for quite some time.

In the first part of this article, I'll explain the most important concepts about rendering in React and how React decides to re-return a given component.

In the last section of this article, I'll evidence y'all what you can do to optimize the render performance of your React awarding.

If, subsequently reading this, you accept open questions or notice an error, feel complimentary to leave a annotate or email me.

Table of Contents
  • Rendering in React

    • What is rendering?
    • What is the VDOM?
    • What does this mean for functioning?
    • Desire to see re-rendering in action?
  • When does React re-render?

    • Why doesn't my React component update when its props change?
  • Strength a React component to rerender

    • Using React's forceUpdate office
    • Forcefulness an update in React hooks
  • How to optimize re-renders

    • Controlling when a component should update
    • Construction of your components
  • Decision

Rendering in React

What is rendering?

If we want to sympathise how React renders and re-renders work, it'south a good thought to understand what happens behind the scenes of the library.

Rendering is a term that can be understood on unlike levels of abstraction. Depending on the context, information technology has a slightly different meaning. In any case, ultimately, it describes the process of generating an image.

To start off, we need to understand what the DOM (Document Object Model) is:

"The W3C Document Object Model (DOM) is a platform and language-neutral interface that allows programs and scripts to dynamically access and update the content, construction, and way of a document."

In plain English, this means that the DOM represents what you encounter on your screen when you open up a website, expressed through the markup linguistic communication HTML.

Browsers allow the JavaScript language to change the DOM through an API: The globally available certificate represents that land of the HTML DOM and provides us with functions to change it.

You can modify the DOM with JavaScript through the DOM programming interface that contains functions like document.write, Node.appendChild or Chemical element.setAttribute.

What is the VDOM?

Then we accept the Virtual DOM (or VDOM) of React, another brainchild layer on superlative of that. It consists of your React application's elements.

State changes in your application will exist practical to the VDOM kickoff. If the new state of the VDOM requires a UI change, the ReactDOM library will efficiently exercise this by trying to update only what needs to exist updated.

For example, if only the attribute of an element changes, React will only update the attribute of the HTML element by calling certificate.setAttribute (or something similar).

React VDOM explained

The red dots correspond updates of the DOM tree.
Updating the VDOM doesn't necessarily trigger an update of the real DOM.

When the VDOM gets updated, React compares it to to a previous snapshot of the VDOM and and so simply updates what has changed in the real DOM. If nothing changed, the real DOM wouldn't be updated at all. This procedure of comparison the old VDOM with the new one is called diffing .

Existent DOM updates are slow because they cause an actual re-draw of the UI. React makes this more efficient by updating the smallest corporeality possible in the real DOM.

Therefore we have to be aware of the difference betwixt native and virtual DOM updates.

Read more than about how this works in React'due south documentation nearly reconciliation.

What does this hateful for performance?

When we talk about renders in React, we really talk about the execution of the render function, which doesn't e'er imply an update of the UI.

Let's see this in an case:

                          const              App              =              (              )              =>              {              const              [message,              setMessage]              =              React.              useState              (              ''              )              ;              return              (                                                <                                >                                                                                          <                  Tile                                message                                  =                  {message}                                />                                                                                          <                  Tile                                />                                                                                          </                                >                            )              ;              }              ;                      

In function components, the execution of the whole role is the equivalent of the render role in class components.

When the country changes in the parent component (in this instance, App), the two Tile components will re-render, fifty-fifty though the second one doesn't even receive any props.

This translates to having the return part being chosen three times, but actual DOM modifications only happen once in the Tile component that displays the bulletin:

React VDOM DOM diffing

The cerise dots again represent renders.
In React, this ways calling the render office. In the real DOM, this means re-painting the UI.

The good news is that you don't have to worry too much virtually the performance bottlenecks of UI re-draws. React already optimizes this for you.

The bad news is: All those red dots on the left-hand side mean that the render office of these components has been executed.

The execution of these return functions has two drawbacks:

  1. React has to run its diffing algorithm on each of those components to cheque whether it should update the UI.
  2. All your code in these render functions or role components will be executed again.

The first betoken is arguably not that of import since React manages to summate the difference quite efficiently. The danger lies in the code that you wrote is beingness executed repeatedly on every React return.

In the instance above, we have a small component tree. Only imagine what happens if each node has more than children, and these once more might take kid components. We'll see how we can optimize this.

Desire to see re-rendering in action?

React DevTools lets you highlight renders under Components -> View Settings -> Highlight updates when components return. This will show you the virtual renders.

If you want to run into native re-renders, you tin can exercise so in the Chrome DevTools, under the 3-dot menu on the right -> More tools -> Rendering -> Paint flashing.

Now click through your application with outset the React re-renders highlighted, and then the native renders, and you'll see how much React optimizes native rendering.

Example of Chrome'due south Paint Flashing option in activeness.

When does React re-render?

Above we saw what causes a re-draw of our UI, merely what is calling React's render function to brainstorm with?

React schedules a render every fourth dimension the land of a component changes.

Scheduling a return means that this doesn't happen immediately. React will effort to find the best moment for this.

Changing the land ways that React triggers an update when we call the setState part (in React hooks, you would employ useState). This doesn't only mean the component'south render function will exist called, only besides that all its subsequent child components will re-render, regardless of whether their props have inverse or not.

If your application is poorly structured, yous might be running a lot more JavaScript than you lot expected because updating the parent node implies running the render function of all children.

In the last role of the article, we will see a few tips that help you to prevent this kind of overhead.

Why doesn't my React component update when its props change?

There are 2 common reasons why React might not update a component even though its props take changed:

  1. The props weren't updated correctly via setState
  2. The reference to the prop stayed the same

As we already saw before, React re-renders a component when you call the setState function to change the state (or the provided part from the useState hook in part components).

As a result, the child components simply update when the parent component's country changes with one of those functions.

Straight mutating the props object is not allowed since this won't trigger any changes, and React doesn't find the changes.

                          this              .props.user.name              =              'Felix'              ;                      

Don't do this!

Instead of irresolute the props similar this, yous need to change the state in the parent component.

                          const              Parent              =              (              )              =>              {                              const                [user,                setUser]                =                React.                useState                (                {                name:                'Felix'                }                )                ;                            const              handleInput              =              (              e              )              =>              {              due east.              preventDefault              (              )              ;                              setUser                (                {                                            ...user,                                            proper name:                e.target.value,                                            }                )                ;                            }              ;              return              (              <              >              <input onChange=              {handleInput}              value=              {user.name}              /              >              <Child user=              {user}              /              >              <              /              >              )              ;              }              ;              const              Child              =              (                              {                user                }                            )              =>              (              <h1>              {user.name}              <              /h1>              )              ;                      

Information technology's important to change the country with the corresponding React functions. You can find the Codepen here.

Note how I update the state using setUser, which is the function I get from React.useState. The equivalent to this in class components would be this.setState.

Force a React component to rerender

In the 2 years that I've been working with React professionally, I've never come to a point where I needed to force a re-return. I encourage yous to read the article from the beginning if that'southward what yous're here for because usually there's a better style of dealing with React components that aren't updating.

Still, if you absolutely need to strength an update, you can practice so with the following methods:

Using React'southward forceUpdate function

This one is the nigh obvious one. In React class components, you can force a re-render by calling this function:

Force an update in React hooks

In React hooks, the forceUpdate function isn't bachelor. You can force an update without altering the components country with React.useState like this:

                          const              [state,              updateState]              =              React.              useState              (              )              ;              const              forceUpdate              =              React.              useCallback              (              (              )              =>              updateState              (              {              }              )              ,              [              ]              )              ;                      

I got this one from StackOverflow. You'll probably never need it.

How to optimize re-renders

An instance of inefficient re-renders is when a parent component controls the state of a kid component. Remember: When the state of a component changes, all children will re-render.

I expanded the example I already used for explaining React.memo to have more nested children. Become alee and try it out.

The numbers in yellow are counting the number of times the return office of each component has been executed:

Paints
0

Play around with the source code on codepen.

Fifty-fifty though we only updated the state of the blueish component, a lot more than renders of other components take been triggered.

Controlling when a component should update

React provides the states with a few functions to prevent these unnecessary updates.

Let's take a look at them, after this, I'll bear witness you another, more effective way of improving render performance.

React.memo

The start one, which I already gave away before, is React.memo. I already wrote a more in-depth article on this, but in summary, it'due south a role that prevents your React Hook components from rendering when the props don't modify.

An instance of this in action looks something similar this:

                                          const                TileMemo                =                React.                memo                (                (                                  {                  children                  }                                )                =>                {                            let              updates              =              React.              useRef              (              0              )              ;              return              (                                                <div                className                                  =                  "black-tile"                                >                                                          Memo                                                                            <                  Updates                                updates                                  =                  {updates.current++                  }                                />                                                                      {children}                                                                                          </div                >                            )              ;              }              )              ;                      

There are a few more than things you need to know about this before using it in product. I recommend you check out my article on React.memo after reading this 1.

The equivalent for React classes is using React.PureComponent.

shouldComponentUpdate

This function is one of React'due south lifecycle functions and allows us to optimize rendering functioning by telling React when to update a class component.

Its arguments are the next props and the next state that the component is well-nigh to render:

                          shouldComponentUpdate              (              nextProps,                nextState              )              {              // return truthful or faux              }                      

This part is pretty easy to use: Returning true causes React to call the render function, returning fake prevents this.

Ready the key attribute

In React, information technology is very common to exercise the following. Discover out what'southward wrong with it:

                                                            <div                >                                                        {              events.              map              (              event              =>                                                <                  Event                                event                                  =                  {event}                                />                            )              }                                                                            </div                >                                    

Here I forgot to gear up the primal attribute. Near linters will warn you lot about this, merely why is it and then important?

In some cases, React relies on the key attribute for identifying components and optimizing performance.

In the example above, if an effect is being added to the first of the array, React will retrieve that the get-go and all the subsequent elements take inverse and will trigger a re-return of those. We can prevent this by adding a fundamental to the element:

                                                            <div                >                                                                      {              events.              map              (              upshot              =>                                                                    <                    Event                                    event                                      =                    {issue}                                    central                                      =                    {event.id}                                    />                                            )              }                                                                            </div                >                                    

Try to avoid using the index of the array as a key and use something that identifies the content.
Keys only have to be unique among siblings.

Structure of your components

An even better mode of improving re-renders is past restructuring your code a picayune bit.

Exist careful where you lot place your logic. If you put everything in the root component of your application, all the React.memo functions in the world won't help you lot to fix your functioning problems.

If you place information technology closer to where the data is used, chances are you don't fifty-fifty demand React.memo.

Check out the optimized version of the example and type in some text:

Paints
0

You see that even though the land updates, the other components don't re-return at all.

The just change I made was to motility lawmaking that handles the state into a seperate component:

                          const              InputSelfHandling              =              (              )              =>              {              const              [text,              setText]              =              React.              useState              (              ''              )              ;              return              (                                                <input                value                                  =                  {text}                                placeholder                                  =                  "Write something"                                onChange                                  =                  {                  (                  east                  )                  =>                  setText                  (e.target.value)                  }                                />                            )              ;              }              ;                      

If you need to apply the state in other parts of your application, you can do so by using React Context or alternatives like MobX and Redux.

In this article, I explain component composition more in detail and how it can help better performance.

Determination

I hope I could give yous a better understanding of how React's return mechanisms work and what y'all can practise to get the most out of this. For this article, I had to practice some additional research about the topic to get a better agreement of how React's return piece of work.

I intend to write more about frontend performance, then if you want to get notified well-nigh the latest articles, follow me on Twitter and subscribe to my E-mail list.

If you came this far, you'll too want to check out my article about React.memo, which explains the API more in depth, some common pitfalls you could encounter, and why you shouldn't ever use React.memo. Cheers for reading.

brooksorsespach62.blogspot.com

Source: https://felixgerschau.com/react-rerender-components/

0 Response to "When State Changes React Does Render Again"

Publicar un comentario

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel