React render method being called every time parent rerenders - reactjs

I have a react component, that I noticed is being rerendered every time the owner component renders, even though the props being passed have not changed.
Is this normal behavior? I thought a component only rerenders if the owner sends in new props, i.e. the props are changed have different values or some internal state changes.
Assuming the above is true are there any tricks to debugging what is changing to cause the component to rerender?

The whole point of React is to use Virtual DOM above actual DOM. render() method in your React Component is used to compute new VD, compare it with previous, and apply diff to AD. And there is a difference between e.g. React.DOM.div and your component in the render() method of another component - React needs to calculate VD of your component - obviously, due it's render() method - even if no props were passed.
However, you can explicitly tell React Component, should it invoke it's render() method or not - using the shouldComponentUpdate() hook. In React.createClass() notation you can use PureRenderMixin, which is nothing except next code injection:
import shallowEqual from 'react/lib/shallowEqual';
shouldComponentUpdate(nextProps, nextState) {
return !shallowEqual(nextProps, this.props) || !shallowEqual(nextState, this.state);
}
There are some ways to do it in ES6 notation - e.g. inheritance from PureRenderComponent, that contains the above hook.
See also https://facebook.github.io/react/docs/advanced-performance.html

Related

Writing optimized React functional components

It is my understanding that the entire React Functional Component gets re-run when re-render is needed or there are any state updates, so how to properly manage the state inside these functions? Is it important to keep it empty of any members like event handlers that you wouldn't want to be re-created every time the function gets re-run?
Is there some sort of best practice for writing optimized functional components?
React Memo is something you might be looking for.
React.memo(...) is a new feature introduced in React v16.6. It works
similiar to React.PureComponent, it helps control functional
components re-renders. React.memo(...) is to functional components
what React.PureComponent is to class components. How do we use
React.memo(…)?
It is very simple. Let’s say we have a functional component, like this:
const Funcomponent = ()=> {
return (
<div>
Hiya!! I am a Funtional component
</div>
)
}
We simply pass the FuncComponent as argument to React.memo function:
const Funcomponent = ()=> {
return (
<div>
Hiya!! I am a Funtional component
</div>
)
}
const MemodFuncComponent = React.memo(FunComponent)
React.memo returned a purified component MemodFuncComponent. This component is what we will render in our JSX markup. Whenever the props and state changes in the component, React will check if the prev state and props and the next props and state are equal if not equal the functional component will re-render if they are equal the functional component will not re-render.
As for second question, yes it's true. You should avoid defining the function inside the render function or in case of functional components, avoid defining inside the function, it will cause unwanted calling of those functions and can result in unwanted behavior as well as cause it to be created every time the component re-renders.
The same goes for adding in-line callback functions for event handlers. They should be defined outside the render function.
As how I get it, You want to know how to manage or improve your react performance right? You are right every Component in react gets re-rendered when there are any state changes in this component or in the parent component (if there is).
So there is a tool (Chrome extension) that helps you finds out which part of the application get re-rendered whenever you make an action React developer tool.

How does react decide to rerender a component

I know React has a life cycle method called shouldComponentUpdate, Which by default return true and that's how the component decides to update
But How does that life cycle method gets called, When a state or props change for that component. What actually happens when we receive new props or state? When We connect a component to redux state and mapStateToProps, Are we checking for a change in values inside the component? If not, When We are looking for a change in state or props?
when the props or state changes, how the life cycle methods are called?. Do we have a listener that calls these methods when the props or state changes?
You should look at lifecycles of both, how they perform and in what order each method gets called. Looking at react lifecycle image bellow you can see the difference between componentWillMount and componentDidMount and others like componentDidUpdate, componentWillUpdate and so on...
Also you should reason when to use each method
To update state you call this.setState() which tells react that something has changed and it will re-render component tree. If you use this.state.data = something react won't trigger render(). Now to update props, you need to understand how render() actually works. This answer is summarized from existing anwser already:
Every time render() is called react will create a new virtual DOM
where the root node is the component whose render function is called.
The render() function is called when either the state or the props of
a component or any of its children change. The render() function
destroys all of the old virtual DOM nodes starting from the root and
creates a brand new virtual DOM.
In order to make sure the re-rendering of components is smooth and
efficient React uses the Diffing Algorithm to reduce the time it takes
to create a new tree to a time complexity of O(n), usually time
complexity for copying trees is > O(n^2). The way it accomplishes this
is by using the "key" attribute on each of the elements in the DOM.
React knows that instead of creating each element from scratch it can
check the "key" attribute on each node in the DOM. This is why you get
a warning if you don't set the "key" attribute of each element, React
uses the keys to vastly increase its rendering speed.
React Lifecycle
Redux Lifecycle
If you use redux library, may be, your component does not re-render after your props changes. Checkout this issue to resolve the props changes problem with componentWillReceiveProps

React will not create a new nested component as expected

In my application I have a page change mechanism that uses one of the properties of parent component state.
So I do something like:
class mainComponent{
state={
mypage:null
}
onclickhandler(page){
this.setState({mypage:page});
}
render(){
return <div>{page}</div>
};
}
In my "page" property I have various input fields and other components.
When I change the page, all inputs get updated with new values. However, my custom nested components are never re-created.
Instead, reach just calls componentDidUpdate on them.
Is there a way to force it to construct a new nested component somehow?
React won't recreate component when it's not needed - it's a part of optimizations and general way react works.
When 'new', 'expected' component exists (the same type, the same or no key id) it only receives updated props.
Updating props sometimes doesn't force rerendering (it's guaranteed for state updates). PureComponent compares props shallowly, you can check shouldComponentUpdate (should return true to force render).

Will a stateless component re-render if its props have not changed?

One thing I had learned about React is that if the props to a component don’t change, then React doesn’t bother re-rendering the component. Is that true for stateless components too? Or do they behave more like “stupid” functions and get executed every time?
For example, if I had:
import StatelessComponent from '../StatelessComponent';
export default class DocumentsTable extends React.Component {
state = {
something: 'foobar',
};
render() {
return (
<div>
{ this.state.something }
<StatelessComponent theOnlyProp='baz'>
</div>
)
}
};
When this.state.something updates its value, does <StatelessComponent> get re-rendered? Or is it “smart” enough to see that its props didn’t change, like other React components?
UPDATE 25.10.2018
Since React 16.6, you can use React.memo for functional components to prevent re-render, similarly to PureComponent for class components:
const MyComponent = React.memo((props) => {
return (
/* markup */
);
});
Also, memo does internal optimization.
And unlike a userland memo() higher-order component implementation, the one built into React can be more efficient by avoiding an extra component layer.
Blockquote
OLD ANSWER
Yes, they always re-render 1 (unless you use React.memo as explained above) if setState() is called in the component itself or one of its parents, because functional stateless components don't carry a shouldComponentUpdate. In fact, each React component is being re-rendered1 unless they implement shouldComponentUpdate.
Important to note is that calling render() doesn't mean that DOM Nodes are being manipulated in any way. The render method just serves the diff algorithm to decide which DOM Nodes need to really be attached / detached. Note that render() is not expensive, it's the DOM manipulations that are expensive. They are executed only if render() returns different virtual trees.
From React's documentation
Just to be clear, rerender in this context means calling render for all components, it doesn’t mean React will unmount and remount them. It will only apply the differences following the rules stated in the previous sections.
Just don't worry and let render() be called unless your component is huge, then you're better off with stateful Component that implements shouldComponentUpdate().
Look here for an interesting discussion.
1 means that render() function of the component is called, not that the underlying DOM node is being manipulated.
See react does not only rerenders only If props are changed it even rerenders itself if any state change is there. In your case the component will rerender as your state is changing. The way react works is based on an algorithm named Reconciliation, what this algorithm does is that it compares your virtual DOM with real DOM and if it sees any change then it rerender your actual DOM by replacing it with your virtual DOM so any change in state will cause rerendering of the whole component.
Will a Stateless component re-render if its props have not changed?
Yes. Stateless render function will be called even if nothing has changed. However, React will in the reconciliation phase compare the virtual DOM (generated by the render function) against the existing DOM. This is far in the pipeline, hence not ideal if the render function was costly to compute.
A Pure component does have a default shallow comparison of the property and would have stopped the render to be executed. See the Pure component as a normal class React component that has a shouldComponentUpdate that compare with a triple equal the existing properties and the new one.
That being said, you can wrap your Stateless component into a Pure Component by using Recompose.pure (https://github.com/acdlite/recompose/blob/master/docs/API.md#pure) which will automatically perform, like the Pure Component, a shallow comparison without compromising on the short syntax of the Stateless component.
import StatelessComponent from '../StatelessComponent';
const PureChildFromStatelessComponent = Recompose.pure(StatelessComponent);
// ...
<PureChildFromStatelessComponent ... />

In what cases does the setState() NOT cause a re-render in a React Component?

I know that usually any change in the props or the state of a React Component causes it to re-render, but what are the scenarios when a setState() call can be made and not cause a re-render?
When inheriting from plain React.Component React will by default call render() on the component when either the parent component re-renders or setState is called in the component.
However, if you implement shouldComponentUpdate() in your React component you will be able to short-circuit the update cycle. This is useful if you only have a limited number of props that are primitive values (string, number, bool) or when working with immutable data structures. Then you can simply do something like this:
shouldComponentUpdate(nextProps, nextState) {
return nextState.name !== this.state.name // Don't re-render if name is equal
}
The default implementation of shouldComponentUpdate() is
shouldComponentUpdate(nextProps, nextState) {
return true;
}
It is also possible to inherit from React.PureComponent which basically implements shallow comparison of your props and state.
I would recommend the following articles for a more in-depth answer:
https://reactjs.org/docs/optimizing-performance.html#avoid-reconciliation
and https://cdb.reacttraining.com/react-inline-functions-and-performance-bdff784f5578 (Especially the section called (PureComponent and shouldComponentUpdate)
It is also useful to understand the difference between what happens when the render-function is called and what the reconciliation algorithm does to update the DOM. More on this here.

Resources