最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - JSX vs component class instancing - Stack Overflow

programmeradmin0浏览0评论

Can somebody explain to me the difference between the following two statements?

let test1 = new CustomComponent();

and

let test2 = <CustomComponent />

The debugger is Chrome gives me:

for test1
CustomComponent {props: undefined, context: undefined, refs: Object, updater: Object, state: Object…}

for test2
Object {$$typeof: Symbol(react.element), key: null, ref: null, props: Object, type: function…}

And how can I get a variable of type of test2, from of variable of the type of test1 ?

Can somebody explain to me the difference between the following two statements?

let test1 = new CustomComponent();

and

let test2 = <CustomComponent />

The debugger is Chrome gives me:

for test1
CustomComponent {props: undefined, context: undefined, refs: Object, updater: Object, state: Object…}

for test2
Object {$$typeof: Symbol(react.element), key: null, ref: null, props: Object, type: function…}

And how can I get a variable of type of test2, from of variable of the type of test1 ?

Share edited Jun 29, 2017 at 14:35 Chris 59.6k20 gold badges120 silver badges142 bronze badges asked Jun 29, 2017 at 12:59 mattmatt 1,0661 gold badge14 silver badges28 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 8

So.

let test1 = new CustomComponent(); is just a regular javascript thing, same thing happens as calling new thing() any other time. Nothing special.

let test2 = <CustomComponent /> this is an JSX statement, and babel does some magic. It piles <CustomComponent /> into React.createElement(CustomComponent , null). So, as you can see it is nothing like calling new, it's calling a React function that creates an element, that react knows how to deal with.

Babel has a REPL tool that you can use to see what it's doing to your source code if you ever want to see quickly what's going on under the hood.

These are two entirely different things, and I honestly cannot see any use case where you would be using the first case. But you sure ask an interesting question...

Finally, to create elements, use React.createElement(), JSX, or an element factory helper. Don’t write elements as plain objects in the real code—just know that they are plain objects under the hood.


new RequirementSection()

This creates an creates an instance of your class and that's pretty much it. You end up with a "dummy" class that doesn't have any of the React logic whatsoever, such as lifecycle methods.

This means that you would have to invoke each class method manually.

Demo:

In this demo we have two ponents, MyApp and Test. I've made the Test ponent so that when it's created a local flag variable is set to false, but before mounting, it's set to true.

As you can see, the flag doesn't get updated from the lifecycle and remains falsey.

class MyApp extends React.Component {
  render() {
    let test = new Test();
    return <div>{test.render()}</div>;
  }
}

class Test extends React.Component {
  constructor() {
    super();
    this.flag = false;
  }
  ponentWillMount() {
    this.flag = true;
  }
  render() {
    return <div>{this.flag ? "flag is true" : "flag is false"}</div>;
  }
}


ReactDOM.render(<MyApp />, document.getElementById("myApp"));
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="myApp"></div>


<RequirementSection />

As you probably know, this is the most mon way of using React. This is JSX and basically translates into:

React.createElement(RequirementSection, null);`

Here, RequirementSection is the class object. What this returns is a ReactElement, which in contrast to the previous example, does include React logic.

Demo:

This demo is similar to the former one, with the difference that we are now using JSX to create a React Element, instead of just instancing a class object.

Indeed, the lifecycle method does run, and the ponent update the flag to true.

class MyApp extends React.Component {
  render() {
    let test = <Test />;
    return <div>{test}</div>;
  }
}

class Test extends React.Component {
  constructor() {
    super();
    this.flag = false;
  }
  ponentWillMount() {
    this.flag = true;
  }
  render() {
    return <div>{this.flag ? "flag is true" : "flag is false"}</div>;
  }
}


ReactDOM.render(<MyApp />, document.getElementById("myApp"));
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="myApp"></div>


Further reading

You may find one of the following links interesting:

  • React Components, Elements and Instances (official documentation)
  • React Without JSX (official documentation)
  • React Top-Level API (official documentation)
Case 1: let test1 = new CustomComponent();

In this case you have created an instance of a ponent. But this is not a React Instance. Your console output looks like an object, but this is not a React Component object. It's just like a instance of a class.

Case 2: let test2 = <CustomComponent />

In this case same things have happened. But React takes responsibility, that created instance of it as React Component object and render it.

You have obviously seen the difference between two outputs.

test2 output has type attribute with value of $$typeof: Symbol(react.element) .

But there is no type attribute in test1 output.

I hope your doubts is solved.

发布评论

评论列表(0)

  1. 暂无评论