Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS - Does render get called any time "setState" is called?

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

If so, why? I thought the idea was that React only rendered as little as needed - when state changed.

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

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

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

Here's the code of the example, as a JS Fiddle, and embedded snippet:

var TimeInChild = React.createClass({     render: function() {         var t = new Date().getTime();          return (             <p>Time in child:{t}</p>         );     } });  var Main = React.createClass({     onTest: function() {         this.setState({'test':'me'});     },      render: function() {         var currentTime = new Date().getTime();          return (             <div onClick={this.onTest}>             <p>Time in main:{currentTime}</p>             <p>Click me to update time</p>             <TimeInChild/>             </div>         );     } });  ReactDOM.render(<Main/>, 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>
like image 408
Brad Parks Avatar asked Jul 13 '14 01:07

Brad Parks


People also ask

What happens when setState is called in render?

render() Calling setState() here makes it possible for a component to produce infinite loops. The render() function should be pure, meaning that it does not modify a component's state. It returns the same result each time it's invoked, and it does not directly interact with the browser.

Is setState called before render?

You may call setState() immediately in componentDidMount() . It will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the render() will be called twice in this case, the user won't see the intermediate state.

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

A second or subsequent render to update the state is called as re-rendering. React components automatically re-render whenever there is a change in their state or props. A simple update of the state, from anywhere in the code, causes all the User Interface (UI) elements to be re-rendered automatically.

Is componentDidMount called after every render?

There is no call to ComponentDidMount. It is only called once after the initial render.


2 Answers

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

By default - yes.

There is a method boolean shouldComponentUpdate(object nextProps, object nextState), each component has this method and it's responsible to determine "should component update (run render function)?" every time you change state or pass new props from parent component.

You can write your own implementation of shouldComponentUpdate method for your component, but default implementation always returns true - meaning always re-run render function.

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

By default, shouldComponentUpdate always returns true to prevent subtle bugs when the state is mutated in place, but if you are careful to always treat the state as immutable and to read-only from props and state in render() then you can override shouldComponentUpdate with an implementation that compares the old props and state to their replacements.

Next part of your question:

If so, why? I thought the idea was that React only rendered as little as needed - when the state changed.

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

  1. Virtual DOM renders: when render method is called it returns a new virtual dom structure of the component. As I mentioned before, this render method is called always when you call setState(), because shouldComponentUpdate always returns true by default. So, by default, there is no optimization here in React.

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

like image 120
Petr Avatar answered Oct 12 '22 05:10

Petr


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 as little as possible. The only 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 example, TimeInChild is a child component of Main, so it also gets re-rendered when the state of Main changes.

  • React doesn't compare state data. When setState is called, it marks the component as dirty (which means it needs to be re-rendered). The important thing to note is that although render method of the component is called, the real DOM is only updated if the output is different from the current DOM tree (a.k.a diffing between the Virtual DOM tree and document's DOM tree). In your example, even though the state data hasn't changed, the time of last change did, making Virtual DOM different from the document's DOM, hence why the HTML is updated.

like image 44
tungd Avatar answered Oct 12 '22 04:10

tungd