I am beginner in React JS. I came across React.memo() a HOC component that basically only re-renders the component if the component execution results are different from its previous result which it memonizes. But why do we need to use it if there is already a concept of Virtual DOM?
Like doesn't the Virtual DOM concept also do the same thing that is not re-rendering the component if the resultant virtual DOM is the same as the main DOM?
If I get it correctly aren't both follow same concept functionality wise?
React rendering happens at multiple levels. The virtual DOM kicks in at React<->Browser, but using React.memo() can reduce the amount of times that your React code needs to be run. In short:
Virtual DOM: Reduces HTML element creation/edits
React.memo(): Reduce React component re-renders (before even touching HTML)
For it's own - yes, similar to Virtual DOM. But from documentation:
[The memo()] component will usually not be re-rendered when its parent component is re-rendered. […] memoization is only a performance optimization. […] React normally re-renders a component whenever its parent re-renders.
So in other words you can use React.memo() to optimize component if you know that even if parent has changed, this component will not change.
React will execute your function component, compare it to the dom and will update if there are changes. If you use React.memo() your function component will not be executed again and it won't be compared to the dom.
So if you have a calculation in your function compoent that takes one second, without React.memo() it will run this calculation again.
Related
Let's say I've triggered an update of a single React component & as we know by default it will trigger the update of all it's children components.
BUT
How does it work in combination with browser's reflow/repaint ?
How does the whole process look like (step by step) after we trigger a single React-component's update?
By default, the child components would be updated as well, however, that only happens in the virtualDOM, and not the actual DOM.
Changes are made to the virtualDOM, React then checks to see which DOM elements/components are changed/updated, and only those are updated in the actual DOM, it's part of the reason why your React app is fast.
You can refer to this thread for more information, though I think they are more so on class component, not functional component.
How does react create a new virtual DOM for a component when it is updated using a setState() call, even when shouldComponentUpdate() returns false?
Does react create the virtual DOM again for all components, even for components on which setState() was not called? I mean suppose setState() is called on child component, does react a new virtual DOM for the parent component also?
Does react create virtual dom even when shouldComponentUpdate returns false ?
No it does not. If shouldComponentUpdate returns false, the re-render for that particular component and its children is not done.
Does react create virtual dom again for all components, even for component on which setstate is not called.
It will create for those components (and its children) whose state or props have changed. But that does not necessarily mean actual DOM update will happen. Also as mentioned above if any of those components return false from shouldComponentUpdate, re-render is stopped for that component and its child trees.
I mean suppose setstate is called on child component, does react new virtual d for parent component also
No. Parent causes child re-renders, not the reverse. React only re-renders that subtree. Not its roots.
That said, a re-render (Virtual DOM creation) does not always mean DOM change. If previous virtual DOM & new virtual DOM for a subtree is same, the actual DOM is left untouched.
React has explained this using a very clear and concise example in their docs.
I'm using ember.js(version 3.7) and I bite confused now. Now, I'm working on optimizing the code part for our app. First I'll try to find What are the things are re-render in components? After getting into this topic I bite confused with it.
In ember they used didRender() method to trigger re-rendering things (jQuery DOM Manipulation, Asnyc function loading,etc...). Right now I don't have much idea about re-render in ember. Can someone explain to me re-render in detail? And, please share if you have any resource about re-render in ember.
Thanks in advance.
didRender hook doesn't about triggering a re-render. It is described as the Guide that you shared the link of:
You can leverage this hook to perform post-processing on the DOM of a component after it's been updated.
You might want to do something about sizes or focuses or scrolls. To achieve that you need to wait till your rendering finishes. Because otherwise you cannot get the exact values and positions of the components. For those cases you can use didRender hook.
For example:
- if you want to focus some parts of the view
- if you want to scroll some parts of the view
- if you want to resize some components
- if you want to call a third-party libraries which tries to access DOM element.
etc. You can use this hook.
For sure, if you do something that affects to component's values, it can trigger a re-render. But this is something that you normally shouldn't do.
Let's have one more clarification of re-render:
As components are rendered, re-rendered and finally removed, Ember provides lifecycle hooks that allow you to run code at specific times in a component's life.
(Ref)
Guide says about 3 main phases (Ref):
Initial Render
Re-render
Component Destroy
In here Re-render means, if an argument or a property of a component changes, it starts to re-render itself. For example, think of a person-card component which displays the properties of a person. Such as {{person-card person=model.person}}. Whenever the person parameter changes, the component will re-render.
The documents have the following to say about forceUpdate:
Calling forceUpdate() will cause render() to be called on the
component, skipping shouldComponentUpdate(). This will trigger the
normal lifecycle methods for child components, including the
shouldComponentUpdate() method of each child. React will still only
update the DOM if the markup changes.
https://reactjs.org/docs/react-component.html#forceupdate
Does this mean that children of the component also have their render function called?
It will "re-render" every child that does not return false inside of its shouldComponentUpdate method, however note that re-rendering !== re-drawing, it will just cause React's diffing algorithm to run.
And only, if the diffing algorithm sees a difference in the current version of the virtual DOM compared to the previous version of the virtual DOM will the specific "changed" part of the UI get re-drawn on the screen.
Is there a way to stop react from removing/changing nodes embedded in a react component.
For example, I have a react component that acts as a container for a non-react component that manages its DOM on its own. Is there a way to mark such components for reactjs, so that it does not modify its DOM?
In my case, I want my react component to be inline-editable by CKeditor, but react always removes/destroys the editor and all the nodes it has added to the DOM, because they were not defined in the react component itself and so it thinks that those elements should not be there.
Any ideas?
If you return false from a shouldComponentUpdate method on your component, then React will step out of the way and the entire reconciliation process will be skipped for that subtree. Of course, this means that you need to manage all DOM mutations yourself in that area and can't take advantage of React.
Take a look at dangerouslySetInnerHTML on https://facebook.github.io/react/tips/dangerously-set-inner-html.html.
This is the method for adding markup that doesn't sticks to React's update methods and also unsupported tags.
This way you can still update your component, while not updating parts of it.