JSX与组件类实例化

时间:2017-06-29 12:59:16

标签: javascript reactjs

有人可以向我解释以下两个陈述之间的区别吗?

let test1 = new CustomComponent();

let test2 = <CustomComponent />

调试器是Chrome给我的:

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…}

如何从 test1 类型的变量中获取 test2 类型的变量?

3 个答案:

答案 0 :(得分:7)

因此。

let test1 = new CustomComponent();只是一个常规的javascript事情,同样的事情发生在任何其他时间调用new thing()。没什么特别的。

let test2 = <CustomComponent />这是一个JSX声明,而且babel做了一些魔术。它将<CustomComponent />编译为React.createElement(CustomComponent , null)。所以,你可以看到它与调用new完全不同,它调用一个React函数来创建一个元素,反应知道如何处理。

Babel有一个REPL工具,您可以使用该工具查看它对您的源代码所做的工作,如果您想要快速了解幕后发生的事情。

答案 1 :(得分:2)

Case 1: let test1 = new CustomComponent();

在这种情况下,您已创建了组件的实例。但事实并非如此 反应实例。您的控制台输出看起来像一个对象,但事实并非如此 一个React Component对象。它就像一个类的实例。

Case 2: let test2 = <CustomComponent />

在这种情况下,同样的事情发生了。但React负责,将其实例创建为React Component对象并进行渲染。

您显然已经看到了两个输出之间的差异。

test2输出的type属性值为 $$ typeof:Symbol(react.element)

但是test1输出中没有type属性。

我希望你的疑虑得到解决。

答案 2 :(得分:1)

这是两个完全不同的东西,老实说,我不会看到你将使用第一个案例的任何用例。但你肯定会问一个有趣的问题......

  

最后,要创建元素,请使用React.createElement()JSXelement factory helper。不要在真实代码中将元素写为普通对象 - 只要知道它们是引擎盖下的普通对象。

new RequirementSection()

这会创建一个类的实例,而且就是这样。你最终会得到一个“虚拟”类,没有任何反应逻辑,例如生命周期方法。

这意味着您必须手动调用每个类方法。

<强>演示:

在此演示中,我们有两个组件MyAppTest。我创建了Test组件,以便在创建时将本地flag变量设置为false,但在安装之前,它设置为true

如您所见,该标志不会从生命周期更新并仍然是假的。

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;
  }
  componentWillMount() {
    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.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="myApp"></div>

<RequirementSection />

您可能知道,这是使用React的最常用方法。这是JSX,基本上是translates into

React.createElement(RequirementSection, null);`

这里,RequirementSection是类对象。返回的是ReactElement,与前面的示例相反, 包含React逻辑。

<强>演示:

这个演示与前一个演示类似,不同之处在于我们现在使用JSX创建一个React Element,而不仅仅是实例化一个类对象。

实际上,生命周期方法确实运行,组件将标志更新为true

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

class Test extends React.Component {
  constructor() {
    super();
    this.flag = false;
  }
  componentWillMount() {
    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.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="myApp"></div>

进一步阅读

您可能会发现以下其中一个链接很有趣: