React Setstate Causes Constructor to Run Again

Source: Twitter logo

Does React re-render all components and sub components every time setState() is called?

If and so, why? I thought the thought was that React only rendered equally lilliputian equally needed - when state changed.

In the following simple example, both classes render again when the text is clicked, despite the fact that the land doesn't alter on subsequent clicks, as the onClick handler always sets the state to the aforementioned value:

                          this.setState({'test':'me'});                      

I would've expected that renders would just happen if state data had changed.

Here'southward the lawmaking of the example, as a JS Dabble, and embedded snippet:

                              var                TimeInChild                =                React.createClass({                render:                role() {                var                t =                new                Appointment().getTime();                return                (                                  <p>Time in child:{t}</p>                                );     } });                var                Principal                =                React.createClass({                onTest:                function() {                this.setState({'test':'me'});     },                render:                function() {                var                currentTime =                new                Date().getTime();                render                (                                  <div                    onClick={this.onTest}>                  <p>Fourth dimension in master:{currentTime}</p>                  <p>Click me to update time</p>                  <TimeInChild/>                  </div>                                );     } });                ReactDOM.render(                  <Main/>                ,                document.torso);            
                              <script                  src="https://cdnjs.cloudflare.com/ajax/libs/react/xv.0.0/react.min.js">                </script>                <script                  src="https://cdnjs.cloudflare.com/ajax/libs/react/fifteen.0.0/react-dom.min.js">                </script>                          

Does React re-return all components and sub-components every time setState is called?

By default - aye.

There is a method boolean shouldComponentUpdate(object nextProps, object nextState), each component has this method and it's responsible to decide "should component update (run render role)?" every fourth dimension you alter country or pass new props from parent component.

You can write your ain implementation of shouldComponentUpdate method for your component, but default implementation e'er returns true - meaning ever re-run return part.

Quote from official docs http://facebook.github.io/react/docs/component-specs.html#updating-shouldcomponentupdate

By default, shouldComponentUpdate always returns true to preclude subtle bugs when the land is mutated in identify, but if you are careful to always care for the state as immutable and to read-only from props and country in render() then y'all tin can override shouldComponentUpdate with an implementation that compares the former props and country to their replacements.

Adjacent function of your question:

If so, why? I idea the idea was that React merely rendered as little as needed - when the state inverse.

There are two steps of what nosotros may call "render":

  1. Virtual DOM renders: when render method is called it returns a new virtual dom structure of the component. Equally I mentioned before, this render method is chosen always when you phone call setState(), because shouldComponentUpdate always returns truthful by default. And so, by default, there is no optimization hither in React.

  2. Native DOM renders: React changes real DOM nodes in your browser simply if they were changed in the Virtual DOM and as picayune as needed - this is that great React'due south feature which optimizes real DOM mutation and makes React fast.

No, React doesn't render everything when the state changes.

  • Whenever a component is dirty (its state changed), that component and its children are re-rendered. This, to some extent, is to re-render equally little as possible. The just time when render isn't called is when some branch is moved to another root, where theoretically we don't need to re-render anything. In your case, TimeInChild is a child component of Primary, so it also gets re-rendered when the state of Main changes.

  • React doesn't compare state information. When setState is called, it marks the component as dirty (which means information technology needs to be re-rendered). The important matter to annotation is that although render method of the component is called, the real DOM is just updated if the output is unlike from the current DOM tree (a.1000.a diffing between the Virtual DOM tree and document's DOM tree). In your case, fifty-fifty though the state data hasn't changed, the fourth dimension of concluding change did, making Virtual DOM different from the document's DOM, hence why the HTML is updated.

Fifty-fifty though it's stated in many of the other answers hither, the component should either:

  • implement shouldComponentUpdate to return simply when state or backdrop change

  • switch to extending a PureComponent, which already implements a shouldComponentUpdate method internally for shallow comparisons.

Here's an example that uses shouldComponentUpdate, which works only for this uncomplicated use case and demonstration purposes. When this is used, the component no longer re-renders itself on each click, and is rendered when showtime displayed, and later it'south been clicked once.

                                  var                  TimeInChild                  =                  React.createClass({                  render:                  function() {                  var                  t =                  new                  Date().getTime();                  return                  (                                      <p>Fourth dimension in child:{t}</p>                                    );     } });                  var                  Principal                  =                  React.createClass({                  onTest:                  function() {                  this.setState({'test':'me'});     },                  shouldComponentUpdate:                  function(nextProps, nextState) {                  if                  (this.state                  ==                  nix)                  return                  truthful;                  if                  (this.state.examination                  == nextState.test)                  render                  imitation;                  return                  true;   },                  render:                  part() {                  var                  currentTime =                  new                  Engagement().getTime();                  return                  (                                      <div                      onClick={this.onTest}>                    <p>Time in main:{currentTime}</p>                    <p>Click me to update time</p>                    <TimeInChild/>                    </div>                                    );     } });                  ReactDOM.render(                    <Chief/>                  ,                  document.body);              
                                  <script                    src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js">                  </script>                  <script                    src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js">                  </script>                              

Yes. It calls the render() method every time we call setState only except when shouldComponentUpdate returns faux.

It seems that the accustomed answers are no longer the case when using React hooks (with primitive values, meet comments on this answer for details). You can see in this code sandbox that the class component is rerendered when the state is gear up to the same value, while in the function component, setting the land to the same value doesn't cause a rerender.

https://codesandbox.io/southward/even so-wave-wouk2?file=/src/App.js

Another reason for "lost update" tin be the next:

  • If the static getDerivedStateFromProps is divers then it is rerun in every update procedure according to official documentation https://reactjs.org/docs/react-component.html#updating.
  • so if that country value comes from props at the offset information technology is overwrite in every update.

If it is the problem then U can avoid setting the state during update, you lot should check the land parameter value like this

                              static                getDerivedStateFromProps(props:                TimeCorrectionProps,                state:                TimeCorrectionState):                TimeCorrectionState                {                return                state ? land : {disable:                false,                timeCorrection: props.timeCorrection}; }                          

Another solution is add a initialized property to state, and set it upwardly in the starting time time (if the state is initialized to non zippo value.)

Not All Components.

the state in component looks like the source of the waterfall of state of the whole APP.

Then the change happens from where the setState chosen. The tree of renders then become called from there. If you've used pure component, the render will be skipped.

Copyright © 2022 QueryThreads

All content on Query Threads is licensed under the Artistic Eatables Attribution-ShareAlike three.0 license (CC Past-SA 3.0).

smalldieupoestan.blogspot.com

Source: https://www.querythreads.com/react-js-does-render-get-called-any-time-set-state-is-called/

0 Response to "React Setstate Causes Constructor to Run Again"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel