React Setstate Causes Constructor to Run Again
Source:
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":
-
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.
-
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 ofPrimary
, so it also gets re-rendered when the state ofMain
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 althoughrender
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 thestate
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).
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