React lifecyle: phases - reactjs

As much as I know, this are the "phases" on a react lifecycle for a component:
Mounting: Mounting is the stage of rendering the JSX returned by the render method itself.
Updating: Updating is the stage when the state of a component is updated and the application is repainted.
Unmounting: As the name suggests Unmounting is the final step of the component lifecycle where the component is removed from the page.
mounting -> updating -> unmounting
I succesfully used it, but i don't know how to mix those 3 "phases" with :
- commit phase
- precommit phase
- render phase
I found this : http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/
I'm not sure if "mounting", "updating" and "unmounting" are phases or somethings else. Can it be the case that phases are: commit, precommit and render. And "mouting, updating and unmounting" are events or stages ?
Any clues?

The "render phase" and "commit phase" are descriptions of the internal process that react goes through to update your page. While it can be useful to understand what's going on in these, the only place you can interact with it is through the various lifecycle hooks, such as componentDidMount, componentDidUpdate, and componentWillUnmount, so those are the things i would recommend you focus your research on.
When it's time to render the page (usually caused by calling this.setState somewhere), react goes through a series of steps in order to update the webpage:
The first group of steps are collectively called the "render phase". In the render phase, react is creating the Virtual DOM. In other words, it's determining what the page is supposed to look like, without actually changing the page. In the simplest form (where we're not skipping any renders with things like react.memo or shouldComponentUpdate), react calls render on the topmost component, and finds out what it returned, and then for each of its children it calls render on those as well until it knows what the whole page should look like.
The second group of steps are called the "commit phase". Now that it knows what the page should look like, it needs to update the actual DOM to match the Virtual DOM. To do this, it compares the current virtual DOM that it got from the render phase with the virtual DOM it got the last time it rendered, and figures out the minimum set of updates in order to make the page look like that.
And now the rendering is done and the page has been updated. During this process it's possible that some components got created for the first time (ie, "mounted"), or they got their props changed (ie, "updated"), or they were removed entirely ("unmounted"). Components that had this happen to them will have their componentDidMount, componentDidUpdate and componentWillUnmount functions called as appropriate.

Render phase: Is used to calculate changes, and may be aborted if the user wants to. If this phase is aborted the DOM isn’t updated.
Pre-commit phase: Is a period where you can read changes made to the VDOM, before they are applied to the actual DOM.
Commit phase: Here the changes are applied and any side effects are triggered.
Mounting: Runs once when the component is created.
Updating: Runs each time a change is made to the component.
Unmounting: Runs once when the component is about to be destroyed.
Have a look at this article for details
https://medium.com/#vmarchesin/the-react-lifecycle-step-by-step-47c0db0bfe73#:~:text=Pre%2Dcommit%20phase%3A%20Is%20a,any%20side%20effects%20are%20triggered.

Related

What are render and commit phase exactly in React JS? And how virtual DOM helps actually?

I have read many blogs on render and commit phase in react. But couldn't understand much exactly. They mention render phase is a slow process and commit phase doesn't takes time.
In simpler words, is rendering checking the current Virtual DOM with previous Virtual DOM starting from the root/or the point where states/props are changed?
And committing is putting the change in the batch which will go in the next batch update to real DOM?
If we consider rendering as a run of diffing algorithm, the function component -
function ReactApp(){
console.log("rendering...");
return (...<Child/>....);
}
function Child(){
console.log("rendering child...");
useEffect(() => {
console.log("mounting child...");
})
return (...);
}
Will render and "rendering..." can be seen in console.
It's mentioned useEffect (all componentDidMount,didupdate,willUnmount) will run only in commit phase.
But if this component has a child component and the parent renders when parents' states changes.
"rendering..." should be visible in console for parent.
"rendering child..." should be visible in console too.
And it does.
But why "mounting child..." can be seen in console, if no states changed for it.
In reconciliation process, only parent's UI update should go into batch.
And child should only be checked by rendering.
This is creating a lot of confusion among words - 'rendering','mounting','committing'.
Also, we can see the changes on changing state instantly, which means real DOM gets updated quickly?
Or the process is quite faster for a human to perceive changes between a react and a non-react app?
If virtual DOM concept is that powerful, why don't browsers already have it in-built?
Sorry if some/all questions seem stupid.
But I really want to know it in a manner I can explain it to a 5 year. Any links to simpler docs would be grateful too.

How is Virtual DOM updated?

Imagine that you've built an application with ReactJs containing a hundred elements. Let's say that in some time, the state of component A changes, and for the sake of simplicity we assume it has only one element and no child component.
My question is: how is Virtual DOM updated in response to the state change?
After a few hours of research, I found two contradictory opinions:
The entire Virtual DOM is torn down; then it is rebuilt from scratch
Only the changed elements are updated in the Virtual DOM.
Unfortunately, official documentation is not clear about this. So, can anybody give the correct answer? (please with supporting reference)
[Edit] : Some parts are imcomplete here, think about reading the comment section !
React update a component when its state or a prop changes. It does a comparison between the previous JSX and the new one and re-render only the differences.
If the parent component has its state or a prop changed, it will be updated.
The child will not be refreshed unless a prop from the parent that is passed to it changes.
Note that the useEffect from the child is triggered first. Knowing that, If you do things that update the state in the child component, then it will be re-rendered everytime (Because the usEffect is triggered everytime if you don't set any dependencies).
Test from Stackblitz - Child Effect is triggered first
Article that made me notice it (I didn't know before this answer :D)
Here is how I understand things in React. To be short, the entire virtual DOM isn't rebuilt from scratch, it's not how JSX comparison works.
I don't have much sources about what I said, but here is the explanation about jsx update from the official documentation. Just that should be enough to eliminate the first point of your list.

How to run effect's cleanup of a component BEFORE rendering another one?

Here's a codesandbox as starter. If you click the Toggle button you'll see the following output in the console:
mount secondcomp
unmount firstcomp
How can I make it the other way arround? So cleanup first component before rendering the second. Is this possible at all?
I do understand that effects are always run after render, but this is not what I want in my situation. In my use case I have a common resource (fetch-as-you-render pattern) whose methods are called upon unmount of first component and on render of second.

componentDidMount does show intermediate state even though React docs suggest otherwise

1st premise:
componentDidMount() is invoked immediately after a component is mounted (inserted into the tree).
2nd premise:
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.
both from https://reactjs.org/docs/react-component.html#componentdidmount
My conclusion:
Based on the above, mounting cannot be the last step in displaying to the browser, otherwise what is rendered and mounted (any intermediate state) before componentDidMount will always be shown.
However, based on my experience, I've found that any state specified in the constructor does in fact get shown before any overriding state changes in componentDidMount.
This is suggesting to me that premise 2 is incorrect. My conclusion is therefore incorrect as well. Mounting must be the final step in displaying to the browser.
Can anyone clear this up for me?
I believe if you set the state in componentDidMount synchronously, the new state will be the only one shown (or at least the switch would happen so fast after rendering it would be impossible to detect).
If you're trying to set it asynchronously, such as using results from a fetch, then you would see the initial state until the async call is completed.

React state update while rendering

I need to update a state in my react app while rendering the content. Is there any option to update state while rendering.
Note: I am very new to react
You can use componentDidUpdate() Lifecycle method.
and inside componentDidUpdate() function update your state.
FYI: componentDidUpdate() calls every time if component gets updtated.
https://reactjs.org/docs/react-component.html
Futureproofing Note: answer relevant to v16.4.
The answer to your question depends on what you mean by saying "while rendering".
When react invokes the render method of a component, it does not really render anything, yet. The results of the render method will undergo "reconciliation", which means that it will be compared to what's rendered at the moment. If a difference is detected, react will actually re-render the DOM, as effectively as it can.
This means that you can not do anything when react is actually rendering / re-rendering the DOM, since your code is not being executed.
You can, however, do something after the render method has been invoked.
As others have stated before me, the componentDidUpdate method is the place.
Note that the fact that this method has been invoked does not necessarily mean react has re-rendered the DOM. It only assures that the component is in sync with the DOM.
Do note that since setting state CAN cause a re-render, so you should really be careful about setting state in componentDidUpdate - or you might cause an infinite loop of sorts.
Even if you correctly implement shouldComponentUpdate, stopping the render cycle from ever reaching cDU- react docs suggest the result of sCU can be taken as a hint in the future, which will break your app in future releases.
So, if you must setState in cDU - you must check that this setState is required, and is not a side-effect of setting the state in the first place.

Resources