I am hearing the term "mount" too many times while learning ReactJS. And there seem to be lifecycle methods and errors regarding this term. What exactly does React mean by mounting?
Examples: componentDidMount() and componentWillMount()
The main job of React is to figure out how to modify the DOM to match what the components want to be rendered on the screen.
React does so by "mounting" (adding nodes to the DOM), "unmounting" (removing them from the DOM), and "updating" (making changes to nodes already in the DOM).
How a React node is represented as a DOM node and where and when it appears in the DOM tree is managed by the top-level API. To get a better idea about what's going on, look at the most simple example possible:
// JSX version: let foo = <FooComponent />;
let foo = React.createElement(FooComponent);
So what is foo and what can you do with it? foo, at the moment, is a plain JavaScript object that looks roughly like this (simplified):
{
type: FooComponent,
props: {}
}
It's currently not anywhere on the page, i.e. it is not a DOM element, doesn't exist anywhere in the DOM tree and, aside from being React element node, has no other meaningful representation in the document. It just tells React what needs to be on the screen if this React element gets rendered. It is not "mounted" yet.
You can tell React to "mount" it into a DOM container by calling:
ReactDOM.render(foo, domContainer);
This tells React it's time to show foo on the page. React will create an instance of the FooComponent class and call its render method. Let's say it renders a <div />, in that case React will create a div DOM node for it, and insert it into the DOM container.
This process of creating instances and DOM nodes corresponding to React components, and inserting them into the DOM, is called mounting.
Note that normally you'd only call ReactDOM.render() to mount the root component(s). You don't need to manually "mount" the child components. Every time a parent component calls setState(), and its render method says a particular child should be rendered for the first time, React will automatically "mount" this child into its parent.
React is an isomorphic/universal framework. That means that there is a virtual representation of the UI component tree, and that is separate from the actual rendering that it outputs in the browser. From the documentation:
React is so fast because it never talks to the DOM directly. React maintains a fast in-memory representation of the DOM.
However, that in-memory representation is not tied directly to the DOM in the browser (even though it is called Virtual DOM, which is an unfortunate and confusing name for an universal apps framework), and it is just a DOM-like data-structure that represents all the UI components hierarchy and additional meta-data. Virtual DOM is just an implementation detail.
"We think the true foundations of React are simply ideas of components and elements: being able to describe what you want to render in a declarative way. These are the pieces shared by all of these different packages. The parts of React specific to certain rendering targets aren't usually what we think of when we think of React." - React js Blog
So, the conclusion is that React is Rendering agnostic, which means that it doesn't care about what is the final output. It can be a DOM Tree in the browser, it can be XML, Native components or JSON.
"As we look at packages like react-native, react-art, react-canvas, and react-three, it's become clear that the beauty and essence of React has nothing to do with browsers or the DOM." - React js Blog
Now, that you know how React works, it is easy to answer your question :)
Mounting is the process of outputting the virtual representation of a component into the final UI representation (e.g. DOM or Native Components).
In a browser that would mean outputting a React Element into an actual DOM element (e.g. an HTML div or li element) in the DOM tree. In a native application that would mean outputting a React element into a native component. You can also write your own renderer and output React components into JSON or XML or even XAML if you have the courage.
So, mounting/unmounting handlers are critical to a React application, because you can only be sure a component is output/rendered when it is mounted. However, the componentDidMount handler is invoked only when rendering to an actual UI representation (DOM or Native Components) but not if you are rendering to an HTML string on the server using renderToString, which makes sense, since the component is not actually mounted until it reaches the browser and executes in it.
And, yes, Mounting is also an unfortunate/confusing name, if you ask me. IMHO componentDidRender and componentWillRender would be much better names.
Mounting refers to the component in React (created DOM nodes) being attached to some part of the document. That's it!
Ignoring React you can think of these two native functions as mounting:
replaceChild
appendChild
Which are likely the most common functions React uses to mount internally.
Think of:
componentWillMount === before-mount
And:
componentDidMount === after-mount
https://facebook.github.io/react/docs/tutorial.html
Here, componentDidMount is a method called automatically by React when a component is rendered.
The concept is that you're telling ReactJS, "please take this thing, this comment box or spinning image or whatever it is I want on the browser page, and go ahead and actually put it on the browser page. When that's done, call my function that I've bound to componentDidMount so I can proceed."
componentWillMount is the opposite. It will fire immediately BEFORE your component renders.
See also here
https://facebook.github.io/react/docs/component-specs.html
Finally, the "mount" term seems to be unique to react.js. I don't think it is a general javascript concept, or even a general browser concept.
Mounting refers to the initial page loading when your React component is first rendered. From React documentation for Mounting: componentDidMount:
Invoked once, only on the client (not on the server), immediately after the initial rendering occurs. At this point in the lifecycle, the component has a DOM representation which you can access via React.findDOMNode(this).
You can contrast this with componentDidUpdate function, which is called everytime that React renders (except for the initial mount).
The main goal of React js is to create reusable components. Here, components are the individual parts of a webpage. For example, in a webpage the header is a component, the footer is a component, a toast notification is a component and etc. The term "mount" tells us that these components are loaded or rendered in the DOM. These are many top-level APIs and methods dealing with this.
To make it simple, mounted means the component has been loaded to the DOM and unmounted means the components has been removed from the DOM.
Related
In the past, our small team have been using Adobe's Target to perform A/B testing.
Before Vue.js, our applications was relatively simple -- just plain vanilla JS. It was fairly straightforward to do any DOM manipulation (or any data manipulation) since not many things on our application's data was decoupled to anything.
As we are transitioning to Vue.js, the concept of modularizing into components and passing information via props would mean that we may not be able to change props directly from Target's perspective.
However, I noticed that Vue Devtools extension allows you to change the props directly.
Is it possible to do the same thing by vanilla JS?
I think it's not natural to change properties from target component. In Vue.js the model is "Data down - Actions up". This means that you pass some data from parent component to child component and if the child component have to change something, it should emit an event and its parent component should listen for it and react to it. If you need flexibility and your data changes dynamically, you can pass objects via the props and also emit event with objects as payload. I think this is how you should approach the new implementation of your application from vanilla JS.
I know this might be a duplicate, but I really have some difficulties understanding this part of React’s reconciliation algorithm.
So Virtual DOM is in memory representation of the Real DOM. And whenever we call setState() React creates another copy of Virtual DOM and compares it with the previous one or it changes existing Virtual DOM and compares it with Real DOM?
Any changes are made or compared within Virtual DOM instances only.
When you do setState, React makes another copy of virtual DOM with the desired change and compares the old and the current virtual dom to only apply the change in the actual DOM in the browser
You can read more about Virtual DOM and its implemntation in the React docs
According to the Reconcilation link within the react docs
Reconciliation is the algorithm behind what is popularly understood as
the "virtual DOM." A high-level description goes something like this:
when you render a React application, a tree of nodes that describes
the app is generated and saved in memory. This tree is then flushed to
the rendering environment — for example, in the case of a browser
application, it's translated to a set of DOM operations. When the app
is updated (usually via setState), a new tree is generated. The new
tree is diffed with the previous tree to compute which operations are
needed to update the rendered app.
I want to prevent re-rendering of the whole tree, so, I thought to use the setNativeProps to update the specific component when needed, but setNativeProps is not working for all components. I am using both setState and setNativeProps in my react native application. The setState works just fine for all components but setNativeProps do not works for all components.
What is the difference between setState & setNativeProps? For what kind of components setNativeProps should and shouldn't be used? A little example will be more appreciated. Thanks !!!
The React-Native Documentation explains this very well :
It is sometimes necessary to make changes directly to a component without using state/props to trigger a re-render of the entire subtree. When using React in the browser for example, you sometimes need to directly modify a DOM node, and the same is true for views in mobile apps. setNativeProps is the React Native equivalent to setting properties directly on a DOM node.
check this link for reference
Use setNativeProps when frequent re-rendering creates a performance bottleneck
so basically the only use case i can see for it, is when you are creating continuous animations and you don't want to affect the performance of your app.
in almost all other cases, setState will be more than enough.
And in case you need to control when your component should re-render check out
shouldComponentUpdate
This is the situation:
This component renders many data as a list. If I use React state/props to control the DOM style(add classes or modify some attributes), React will always run the render() function when user reacts with the list, like mouseover, click and etc..
Though React has virtual DOM technology, but I think it is still very inefficient to run render() every time. The documents do not recommend to manipulate DOM directly, but I think it is more efficient. What should I do? Thx.
I wouldn't mix writing React with directly manipulating the DOM; do either but not both.
If you are already using React, just use it for what you want. If possible, break the components into as small of pieces as possible; this will help the number renders.
It may be slightly more inefficient to have React re-render too much, but remember that React has been heavily optimized for DOM manipulation.
As far as rerendering in react is concerned, it has been heavily optimised. You may think that the render() function runs on every small manipulation but the thing that is not visibile is that the rerender doesn't occur for the entire DOM rather on only the portion that has changed.
React uses the virtual DOM technology and then it takes out the difference between the current and the virtual dom much like string comparison and then only renders the difference and is thus highly efficient.
So I would recommend you to follow the documentation and not mix DOM manipulation with react.
When writing tests for React components, you have to render them into the DOM in order to make assertions about their correctness. For example, if you want to test that a certain class is added to a node given a certain state, you have to render into a DOM node, then inspect that DOM node via the normal DOM API.
The thing is, considering React maintains a virtual DOM into which it renders, why can't we just assert on the virtual DOM once the component is rendered? That seems to me like a very good reason to have something like the virtual DOM.
Have I missed something?
You haven't really missed anything. We're working on making this better. The virtual parts have always been very much an implementation detail of React, not exposed in any useful or reliable way for testing. We have some methods in our test helpers which wrap up the internal lookups which sometimes avoids looking at the actual DOM but we need more.