Difference between React Component and React Eleme

2020-01-30 04:57发布

What is the difference between React Component and React Element? The documentation mentions both but does not go into detail, some methods require components, other elements...

11条回答
干净又极端
2楼-- · 2020-01-30 05:26

React Elements

A React Element is just a plain old JavaScript Object without own methods. It has essentially four properties:

  • type, a String representing an HTML tag or a reference referring to a React Component
  • key, a String to uniquely identify an React Element
  • ref, a reference to access either the underlying DOM node or React Component Instance)
  • props (properties Object)

A React Element is not an instance of a React Component. It is just a simplified "description" of how the React Component Instance (or depending on the type an HTML tag) to be created should look like.

A React Element that describes a React Component doesn't know to which DOM node it is eventually rendered - this association is abstracted and will be resolved while rendering.

React Elements may contain child elements and thus are capable of forming element trees, which represent the Virtual DOM tree.

React Components and React Component Instances

A custom React Component is either created by React.createClass or by extending React.Component (ES2015). If a React Component is instantiated it expects a props Object and returns an instance, which is referred to as a React Component Instance.

A React Component can contain state and has access to the React Lifecycle methods. It must have at least a render method, which returns a React Element(-tree) when invoked. Please note that you never construct React Component Instances yourself but let React create it for you.

查看更多
干净又极端
3楼-- · 2020-01-30 05:27

To further elaborate on the answer, a React Element does not have any methods and nothing on the prototype. This also makes them fast.

"A ReactElement is a light, stateless, immutable, virtual representation of a DOM Element" - Glossary of React Terms

A react component render() function returns a DOM tree of react elements behind the scenes (This is the virtual DOM btw). There is some complex mapping and diff logic involved, but basically these React elements map to the DOM elements.

You can also create a Element directly React.createElement(arg) where arg can be a html tag name, or a React Component class.

查看更多
Emotional °昔
4楼-- · 2020-01-30 05:34

Here is my take :

Element is the thing that describes how to construct the VDOM. It's basically a "frozen" version of the corresponding Component Instance.

If everything would be functional component then there would be no need for an extra react Element. The functional component hierarchy could produce the VDOM tree directly.

A react Component Instance hierarchy (tree) is a "factory", and that factory is parametrized by the props which are fed to the root react Component Instance and by all the state "stored" anywhere in the Component Instance tree.

So the react Element is basically an "abstract syntax tree" which gets compiled into the actual VDOM.

So why not generate the VDOM directly by using the react Component Instances ? This is the real question here.

At the first glance I don't see why it would not be possible to do so. So most likely the answer is that it's a question of performance.

The react Element is one layer of abstraction between the VDOM and the Component Instance, why this abstraction is needed is not entirely clear to me, most likely it allows optimizations. For example the Element tree does not get rendered completely if some lifecycle method on the Component Instance says that there is no need to render that subtree.

Now, in this case, the logic which handles this optimization "needs" this extra layer of indirection - because the information needs to be stored somewhere that some part of the VDOM should not be compared with the new VDOM, even more, maybe the new VDOM should not be even calculated at all. So using an extra layer of indirection makes the rendering logic simpler and leads to a cleaner, more maintainable implementation - I imagine.

This concept in Haskell is called "lifting" :

For example monads in Haskell are perfect examples of such liftings.

A monad is sort of a description of a computation that can be stored as a value, like 42. Similarly, react Elements are elments of a description on how to compute the "new" VDOM. If somebody wants to compute it.

This talk describes this concept of an "extra" indirection with some simple examples :

In other words : premature optimization is the root of all evil.

Or :Fundamental theorem of software engineering

The fundamental theorem of software engineering (FTSE) is a term originated by Andrew Koenig to describe a remark by Butler Lampson1 attributed to the late David J. Wheeler:2

We can solve any problem by introducing an extra level of indirection.

So, in my understanding react Elements are an implementation detail to handle complexity gracefully and allow some optimization (performance). I don't see why one could not get rid of this extra indirection - in principle - react would still work "just as well" - but it might be super slow, implementing and maintaining the react "engine" itself would be probably a nightmare.

Please correct me if I am missing here something.

Quoting an IMPORTANT part of user6445533's answer :

type, a String representing an HTML tag or a reference referring to a React Component

THIS IS THE KEY ^^^^

Element IS NOT VDOM.

查看更多
走好不送
5楼-- · 2020-01-30 05:35

A React Element is what you would consider to be a basic html(dom to be precise) element. It is just a way of creating element without using the much controversial jsx format.

A React Component is what you can consider as an object. It has its methods, supports React lifecycles and is generally unreusable (at least haven't found any reuse yet, welcome to examples). It necessarily needs to have a render function.

A React Class is what you call a class. Functionality wise React Class and React Component are same. Only syntax is the real change, as React Component is based on ES6 syntax. Another major change is the default binding of functions to this is no longer supported unless using arrow functions. Mixins also are no longer supported as of ES6.

查看更多
干净又极端
6楼-- · 2020-01-30 05:38

An element is a plain object describing what you want to appear on the screen in terms of the DOM nodes or other components. Elements can contain other elements in their props. Creating a React element is cheap. Once an element is created, it is never mutated. The object representation of React element would be as follows,

const element = React.createElement(
  'div',
  {id: 'login-btn'},
  'Login'
)

The above createElement returns as object as below,

{
  type: 'div',
  props: {
    children: 'Login',
    id: 'login-btn'
  }
}

And finally it renders to the DOM using ReactDOM.render as below,

<div id='login-btn'>Login</div>

Whereas a component can be declared in several different ways. It can be a class with a render() method. Alternatively, in simple cases, it can be defined as a function. In either case, it takes props as an input, and returns an element tree as the output. JSX transpiled as createElement at the end.

function Button ({ onLogin }) {
  return React.createElement(
    'div',
    {id: 'login-btn', onClick: onLogin},
    'Login'
  )
}
查看更多
疯言疯语
7楼-- · 2020-01-30 05:39

Consider the Component as a Class, and Element as an instance. That's it!

查看更多
登录 后发表回答