日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

【译】为什么要写super(props)

發(fā)布時(shí)間:2023/11/27 生活经验 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【译】为什么要写super(props) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

譯注:
原文地址 https://overreacted.io/why-do-we-write-super-props/

正文

我聽說Hooks是新的熱點(diǎn)。好笑的是,我想通過描述一些關(guān)于class組件的事實(shí)來作為第一篇博客。這個(gè)想法怎么樣!
這些陷阱對(duì)于有效的使用React并不重要。但是如果你喜歡深入挖掘運(yùn)行機(jī)制,就會(huì)發(fā)現(xiàn)這些東西的又去之處。
下面介紹第一個(gè)。
我寫過很多次 super(props) 但很多情況下,我并不了解為什么要寫它。

class Checkbox extends React.Component {constructor(props) {super(props);this.state = { isOn: true };}// ...
}

當(dāng)然,class fields 提案讓我們可以跳過這步操作。

class Checkbox extends React.Component {state = { isOn: true };// ...
}

之前計(jì)劃的一種支持plain class的語法(注:即類變量),已經(jīng)在2015年,React0.13版中加入。在class fields完整確定之前,定義 constructor 和調(diào)用 super(props) 被當(dāng)做一種臨時(shí)方案。
但是,讓我們回到只使用ES2015的例子里:

class Checkbox extends React.Component {constructor(props) {super(props);this.state = { isOn: true };}// ...
}

為什么要調(diào)用 super? 能不能不用它?如果不得不用它,在調(diào)用它時(shí),發(fā)生了什么?還有其他的參數(shù)嗎?


在JavaScript里,super指向父類構(gòu)造器。(在我們的例子里, 他指向React.Component實(shí)現(xiàn)類)。
重點(diǎn)在于,如果調(diào)用了父類構(gòu)造器,在調(diào)用super之前,無法使用this關(guān)鍵字。JavaScript不允許這么干。

class Checkbox extends React.Component {constructor(props) {// ? Can’t use `this` yetsuper(props);// ? Now it’s okay thoughthis.state = { isOn: true };}// ...
}

為什么JavaScript強(qiáng)制在調(diào)用this之前執(zhí)行父類構(gòu)造器?這里有一個(gè)好的解釋。考慮一個(gè)類的層級(jí)結(jié)構(gòu):

class Person {constructor(name) {this.name = name;}
}class PolitePerson extends Person {constructor(name) {this.greetColleagues(); // ? This is disallowed, read below whysuper(name);}greetColleagues() {alert('Good morning folks!');}
}

想象一下如果在super之前使用this是允許的。一個(gè)月之后,我們可能修改greetColleagues來動(dòng)態(tài)加載信息中的姓名。

greetColleagues() {alert('Good morning folks!');alert('My name is ' + this.name + ', nice to meet you!');
}

但是我們忘記了this.greetColleagues()是在super()之前調(diào)用,它已經(jīng)和this.name建立了聯(lián)系。而this.name甚至還沒有定義。你能發(fā)現(xiàn),像這樣的代碼,真的很難理解。
為了避免這樣的陷阱, 如果在構(gòu)造器中調(diào)用this,JavaScript強(qiáng)制要求super要在this之前書寫,讓父類做它們應(yīng)該做的事。這條限制也被應(yīng)用到了React組件類定義中:

constructor(props) {super(props);// ? Okay to use `this` nowthis.state = { isOn: true };
}

這樣就留給我們另一個(gè)問題: 為什么要傳遞props


你也許覺得對(duì)于React.Component構(gòu)造器初始化this.props而言,通過super傳遞props非常重要。

// Inside React
class Component {constructor(props) {this.props = props;// ...}
}

這和真相相去甚遠(yuǎn)。事實(shí)上,這才是它做了什么。
但不知道為啥,即使你不傳入props,直接調(diào)用super(),還是可以在render和其他方法里訪問到this.props(如果你不相信我,自己試一下)。
這是怎么個(gè)情況?它實(shí)際上證實(shí)了React也會(huì)在調(diào)用constructor之后,立刻合并props

// Inside React
const instance = new YourComponent(props);
instance.props = props;

所以即使你忘記把props傳遞給super(),React也會(huì)及時(shí)設(shè)置上去的。下面是原因之一:

當(dāng)React支持類方法聲明組件時(shí),并不是單單支持了ES6類語法。它的目標(biāo)是支持所有抽象類范圍內(nèi)的聲明方法。JavaScript有很多變種,如ClojureScript, CoffeeScript, ES6, Fable, Scala.js, TypeScript,或者是其他方式,并不是很好比較到底哪種方式去定義一個(gè)組件更合適。所以React故意固執(zhí)得要求super(),雖然ES6 class是這樣。
這下明白為什么能只寫super()而不用寫super(props)了嗎?
也許還不明白,沒關(guān)系,這個(gè)東西太令人困惑了。當(dāng)然,React將會(huì)在構(gòu)造器執(zhí)行完畢后去合并this.props。但是在super和構(gòu)造器結(jié)尾之間,this.props仍是undefined。

// Inside React
class Component {constructor(props) {this.props = props;// ...}
}// Inside your code
class Button extends React.Component {constructor(props) {super(); // ? We forgot to pass propsconsole.log(props);      // ? {}console.log(this.props); // ? undefined }// ...
}

如果一些方法在構(gòu)造器中調(diào)用,這樣會(huì)給debug造成很大的挑戰(zhàn)。這也是為什么我推薦傳遞super(props),雖然它不是必須的。

class Button extends React.Component {constructor(props) {super(props); // ? We passed propsconsole.log(props);      // ? {}console.log(this.props); // ? {}}// ...
}

這樣確保了this.props在構(gòu)造器存在前就已經(jīng)被設(shè)置。


還有一點(diǎn),React長期使用者可能會(huì)好奇。
你也許注意到了Context API傳遞了第二個(gè)參數(shù)給構(gòu)造器。(不論是古老的contextTypes還是現(xiàn)在16.6新加的ContextAPI)。
為什么要寫super(props, context)來代替super(props)?當(dāng)然也行,但是context很少使用,所以這個(gè)陷阱不常出現(xiàn)。
在class fields提案通過之后,這些陷阱都沒得差不多了。沒有一個(gè)明確的constructor,所有的參數(shù)都會(huì)自動(dòng)傳遞。這也是為什么一個(gè)表達(dá)式類似state={}可以包含this.propsthis.context引用。
通過使用Hooks,就不需要superthis了。但那是另一個(gè)主題了。

轉(zhuǎn)載于:https://www.cnblogs.com/liuyongjia/p/10140071.html

總結(jié)

以上是生活随笔為你收集整理的【译】为什么要写super(props)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。