我听说 Hooks 最近很火。讽刺的是,我想用一些关于 class 组件的有趣故事来开始这篇文章。你觉得如何?
本文中这些坑对于你正常使用 React 并不是很重要。 但是假如你想更深入的了解它的运作方式,就会发现实际上它们很有趣。
开始第一个。
首先在我的职业生涯中写过的super(props)
自己都记不清:
class Checkbox extends React.Component { constructor(props) { super(props); this.state = { isOn: true }; } // ...}
当然,在类字段提案 (class fields proposal) 中建议让我们跳过这个开头:
class Checkbox extends React.Component { state = { isOn: true }; // ...}
在2015年 React 0.13 增加对普通类的支持时,曾经打算用这样的语法。定义constructor
和调用super(props)
始终是一个临时的解决方案,可能要等到类字段能够提供在工程学上不那么反人类的替代方案。
不过还是让我们回到前面这个例子,这次只用ES2015的特性:
class Checkbox extends React.Component { constructor(props) { super(props); this.state = { isOn: true }; } // ...}
为什么我们要调用super
? 可以调用它吗? 如果必须要调用,不传递prop
参数会发生什么? 还有其他参数吗? 接下来我们试一试:
在 JavaScript 中,super
指的是父类的构造函数。(在我们的示例中,它指向React.Component
的实现。)
重要的是,在调用父类构造函数之前,你不能在构造函数中使用this
。 JavaScript 是不会让你这样做的:
class Checkbox extends React.Component { constructor(props) { // 这里还不能用 `this` super(props); // 现在可以用了 this.state = { isOn: true }; } // ...}
为什么 JavaScript 在使用this
之前要先强制执行父构造函数,有一个很好的理由能够解释。 先看下面这个类的结构:
class Person { constructor(name) { this.name = name; }}class PolitePerson extends Person { constructor(name) { this.greetColleagues(); //这行代码是无效的,后面告诉你为什么 super(name); } greetColleagues() { alert('Good morning folks!'); }}
如果允许在调用super
之前使用this
的话。一段时间后,我们可能会修改greetColleagues
,并在提示消息中添加Person
的name
:
greetColleagues() { alert('Good morning folks!'); alert('My name is ' + this.name + ', nice to meet you!'); }
但是我们忘记了super()
在设置this.name
之前先调用了this.greetColleagues()
。 所以此时this.name
还没有定义! 如你所见,像这样的代码很难想到问题出在哪里。
新闻热点
疑难解答
图片精选