有人可以向我解释以下两个陈述之间的区别吗?
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 类型的变量?
答案 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()
,JSX或element factory helper。不要在真实代码中将元素写为普通对象 - 只要知道它们是引擎盖下的普通对象。
new RequirementSection()
这会创建一个类的实例,而且就是这样。你最终会得到一个“虚拟”类,没有任何反应逻辑,例如生命周期方法。
这意味着您必须手动调用每个类方法。
<强>演示:强>
在此演示中,我们有两个组件MyApp
和Test
。我创建了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>
您可能会发现以下其中一个链接很有趣: