Selective children component render - reactjs

A basic question I need help here.
Whenever this.setState invoked at parent components, all the children components will be rendered. This will cause the performance issue if I have huge amount of child components.
Lets give an example,
Parent Component
handleToggleTick() {
const newObj = Object.assign({}, this.state, { iconName: ''});
this.setState({
iconName: newObj.iconName,
});
}
render() {
return(
<ChildComponentA iconName={this.state.iconName} toggleTick={() => this.handleToggleTick}></ChildComponentA>
<ChildComponentB></ChildComponentA>
<ChildComponentC></ChildComponentA>
)
}
Based on the example above, whenever handleToggleTick invoked from childcomponentA, setState invoked for new iconName. What I want is, only ChildComponentA only the one get render since props.iconName is related to it, but not for childcomponentB and childcomponentC.
I understand there is an option to check shouldComponentUpdate in childcomponent to prevent it get render. But, imagine I have over 100 of childcomponent, would it be frustrating to write over 100 times of shouldComponentUpdate method?
I need help here, please advice!

React doesn't provide any way to render children selectively. The component will either render or not. But I need to highlight a few points why this is not a problem when we use React in practice.
First of all, you don't need to manually implement shouldComponentUpdate for each component. If you don't want to rerender component if its props and state haven't changed, you can just extend from the PureComponent class instead of the Component class. Note that React.PureComponent's shouldComponentUpdate() only uses shallow comparison for state and props. But this shouldn't be a problem if you follow react best practices and avoid mutating the state.
Also, it's not practical to have more than 100 different components in one render method. React always encourages decomposing your UI into smaller components and using component composition. When we follow this approach, components will be nested inside each other in different levels instead of having a large number of components in one render method.
What I'm trying to explain is it's more practical and easy to manage when we compose our component in a nested fashion (2) rather than having lots of components inside a big container component (1).
In your example, if ChildComponentB and ChildComponentC are inside another component called ChildConatainerComponent then we only need to implement shouldComponentUpdate() for ChildConatainerComponent. Then it will automatically stop rendering any child element inside it.
render() {
return(
<ChildComponentA iconName={this.state.iconName}
toggleTick={() => this.handleToggleTick}/>
<ChildConatainerComponent/>
)
}
class ChildConatainerComponent extends PureComponent {
render() {
return (
<div>
<ChildComponentB/>
<ChildComponentC/>
</div>
);
}
}
Another very import concept to keep in mind is calling render function doesn't mean that React recreates all the DOM elements again. The render method only make changes to React virtual DOM which is an in-memory representation of DOM and it's faster than actual DOM. Then React compare versions of virtual DOM which are before the update and after the update and the actual DOM will be updated with only what has actually changed.

Another solution you could consider is moving iconName into ChildComponentA, considering this is the only component related to it.

Related

It is necessary to memorize a Small/Cheap Component ? - ReactJS

Lets say i have a child component that just return a div element
Child Component :
function Child() {
return <div className={styles.alertBox}>No Data Found</div>;
}
it will always re-render when the parent state change, so to prevent it re-render we will wrap it using React.memo
example :
export default function Parent(){
*some state and setState stuff*
const MemorizeChild = React.memo(Child)
return MemorizeChild
By doing that we prevent our Child Component to re-render everytime we change the state
My Question is:
did we really need to memorize the Child Component although it just return few line of html and does not execute some heavy function, because we all know that Memorizaition are not Free. in return of Time we trade space (Memory / Cache). if it not can you tell me when should i memorize my component
I would say that it doesn't make much sense to memoize such a component.
There is already a similar question, take a look.
It should be used if it's possible to quantify the performance gains from it.
Shortly I suggest using memo when:
you know that a component will render quite often
component re-renders with the same props
component is big enough to have props equality check
Also, you can use profiler to measure how often a React application renders and what the “cost” of rendering is. It can help you identify what parts of an application might need memoization.

react native re-rendered components multiple times

In react native, I use some component like audio player, header etc. Also, I use console.log() for debugging for component I put log in start of components :
const MiniPlayer = (props) => {
console.log('Begain Mini Player ....');
return()
}
I got multiple logs, it's re-rendering is happening multiple time without any special event or state change.
app hasn't any issue and not working slow.
Should I control this re-rendering or is it common in react ?
As per your given snippet, MiniPlayer will re-render whenever its parent component re-renders. It's how react works. If a component updates, its entire subtree re-renders regardless whether the children components need it or not. To control it, you can use shouldComponentUpdate in a class component or extend the class with PureComponent, or wrap your component with React.Memo if it's a functional component. Since yours is a functional component, we can make changes to your component so that it re-renders only when its props change as follows.
const MiniPlayer = React.Memo((props) => {
console.log('Begain Mini Player ....');
return()
})
More resources here - shouldComponentUpdate, PureComponent and React.Memo
Also remember that using React.Memo is just going to perform a shallow comparison of props. So even if the values of props are equal but if the reference changes, it would still cause a re-render.
Should you control this re-rendering? Well that depends. If your component is a costly one which performs heavy computations whenever it updates, then you should control this, else it is not going to affect much, as the DOM anyways is going to perform a diff check to determine what is supposed to be updated.

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.

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 ... />

Difference between using a HOC vs. Component Wrapping

I just checked out HOC's in React. They are pretty cool. However, doesn't simply wrapping a component achieve the same result?
Higher Order Component
This simple HOC passes state as properties to the ComposedComponent
const HOC = ComposedComponent => class extends React.Component {
... lifecycle, state, etc;...
render() {
return (<ComposedComponent {...this.state} />);
}
}
Component Wrapping
This component passes state as properties to the child component
class ParentComponent extends React.Component {
... lifecycle, state, etc;...
render() {
return (
<div>
{React.cloneElement(this.props.children, { ...this.state })}
</div>
);
}
}
Although usage is slightly different between the two, they both seem to be equally as reusable.
Where is the real difference between HOC's and composing components via this.props.children? Are there examples where you can only use one or the other? It is a better practice to use HOC's. Are these just choices that you have where you get to pick your preferred flavor?
Higher-Order Components (HOC) and Container Components are different. They have different use cases and solve similar, but different problems.
HOC are like mixins. They are used to compose functionality that the decorated component is aware of. This is opposed to Container Components that wrap children and allow the children to be dumb (or not aware of the Container's decorated functionality).
It is true when transferring props, that Containers can add functionality to their children. But, this is usually in the form of props being passed down to the children. In Containers, this is also awkward because of the limitation that you cannot simply add props to an already created Element:
So, if you wanted to add a new prop to a child from this.props.children, you would have to use cloneElement. This is not as efficient because it means you have to re-create the elements.
Also, HOC is simply a way (factory) for creating Components. So, this can happen outside the render.
I just wanted to add that when you need to dynamic higher order components the Container approach works better.
If you e.g have 4 elements to render that could have a HOC defined, you would like to create the Higher Order Component inside render, but since calling higher order components inside render causes the <HigherOrderComponent/>'s to remount on every render this becomes a very bad Idea.
This is documented here; https://github.com/facebook/react/blob/044015760883d03f060301a15beef17909abbf71/docs/docs/higher-order-components.md#dont-use-hocs-inside-the-render-method.
But in general I would go for the HOC approach.

Resources