我聽說 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還沒有定義! 如你所見,像這樣的代碼很難想到問題出在哪里。
新聞熱點
疑難解答
圖片精選