Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between `React.createElement(...)` and `new MyComponent()`?

Intro: I'm a bit confused with React. I've seen articles saying that React components are just functions that receive the props and render to the virtual DOM. What I see, however, is that they are full-blown stateful monsters and I have found no way to treat them like functions.

The question: Why is each usage of a React component wrapped in React.createElement? Why can't I use new MyComponent() instead? It looks pretty similar when I do it in DevTools. Why is React.createElement needed at all, given that components are created using React.createClass? It looks like redundant to me.

Edit: this looks relevant: https://gist.github.com/sebmarkbage/ae327f2eda03bf165261

Edit #2: This is related, but not a duplicate of React.Component vs React.createClass, that question asks about creating classes. I'm not asking about creating new component classes, I'm asking about creating instances (elements) of that classes.

like image 261
mik01aj Avatar asked Nov 10 '22 11:11

mik01aj


1 Answers

I think I found the answer here:

In React 0.12, we're making a core change to how React.createClass(...) and JSX works.

(...)

Currently var Button = React.createClass(...) does two things. It creates a class and a helper function to create ReactElements. It is essentially equivalent to this:

class ButtonClass { }

function ButtonFactory(...args) {   return
React.createElement(ButtonClass, ...args); }

module.exports = ButtonFactory; ```

Then you access this in the consuming component by invoking the ButtonFactory.

var Button = require('Button');

class App {   render() {
    return Button({ prop: 'foo '}); // ReactElement
} }

Conceptually this is the wrong model. The source component should not be responsible for the output of App.

There are a few problems with this:

  • ES6 classes can't be directly exported, they need to be wrapped.
  • There's no convenient way to access the actual class and it's confusing which one you're using.
  • Static methods are wrapped in helpers that are not real function. As a convenience.
  • Auto-mocking destroys the factory so there is no way to test the result of render without disabling mocking.
  • Factories can be wrapped by other factories that returns something different than ReactElements. Making testing and optimizations impossible.
  • Languages with specialized features for object management have to defer to React instead of using the built-in features.
like image 59
mik01aj Avatar answered Nov 15 '22 11:11

mik01aj