摘要:好的方案在構(gòu)造函數(shù)中仍然使用,現(xiàn)在我們只要繞過(guò)每次渲染都要生成新的函數(shù)的問(wèn)題就可以了。我們可以通過(guò)只在構(gòu)造函數(shù)中綁定回調(diào)的上下問(wèn)來(lái)解決這個(gè)問(wèn)題,因?yàn)闃?gòu)造函數(shù)只會(huì)調(diào)用一次,而不是每次渲染都調(diào)用。
原文:Binding callbacks in React components
在組件中給事件綁定處理函數(shù)是很常見(jiàn)的,比如說(shuō)每當(dāng)用戶點(diǎn)擊一個(gè)button的時(shí)候使用console.log打印一些東西。
class DankButton extends React.Component { render() { return } handleClick() { console.log(`such knowledge`) } }
很好,這段代碼會(huì)滿足你的需求,那現(xiàn)在如果我想在handleClick()內(nèi)調(diào)用另外一個(gè)方法,比如logPhrase()
class DankButton extends React.Component { render() { return } handleClick() { this.logPhrase() } logPhrase() { console.log("such gnawledge") } }
這樣竟然不行,會(huì)得到如下的錯(cuò)誤提醒
TypeError: this.logPhrase is not a function at handleClick (file.js:36:12)
當(dāng)我們把handleClick綁定到 onClick的時(shí)候我們傳遞的是一個(gè)函數(shù)的引用,真正調(diào)用handleClick的是事件處理系統(tǒng)。因此handleClick 的this上下文和我門(mén)想象的this.logPhrase()是不一樣的。
這里有一些方法可以讓this指向DankButton組件。
不好的方案 1:箭頭函數(shù)箭頭函數(shù)是在ES6中引入的,是一個(gè)寫(xiě)匿名函數(shù)比較簡(jiǎn)潔的方式,它不僅僅是包裝匿名函數(shù)的語(yǔ)法糖,箭頭函數(shù)沒(méi)有自己的上下問(wèn),它會(huì)使用被定義的時(shí)候的this作為上下文,我們可以利用這個(gè)特性,給onClick綁定一個(gè)箭頭函數(shù)。
class DankButton extends React.Component { render() { // Bad Solution: An arrow function! return } handleClick() { this.logPhrase() } logPhrase() { console.log("such gnawledge") } }
然而,我并不推薦這種解決方式,因?yàn)榧^函數(shù)定義在render內(nèi)部,組件每次重新渲染都會(huì)創(chuàng)建一個(gè)新的箭頭函數(shù),在React中渲染是很快捷的,所以重新渲染會(huì)經(jīng)常發(fā)生,這就意味著前面渲染中產(chǎn)生的函數(shù)會(huì)堆在內(nèi)存中,強(qiáng)制垃圾回收機(jī)制清空它們,這是很花費(fèi)性能的。
不好的方案 2:this.handleClick.bind(this)另外一個(gè)解決這個(gè)問(wèn)題的方案是,把回調(diào)綁定到正確的上下問(wèn)this
class DankButton extends React.Component { render() { // Bad Solution: Bind that callback! return } handleClick() { this.logPhrase() } logPhrase() { console.log("such gnawledge") } }
這個(gè)方案和箭頭函數(shù)有同樣的問(wèn)題,在每次render的時(shí)候都會(huì)創(chuàng)建一個(gè)新的函數(shù),但是為什么沒(méi)有使用匿名函數(shù)也會(huì)這樣呢,下面就是答案。
function test() {} const testCopy = test const boundTest = test.bind(this) console.log(testCopy === test) // true console.log(boundTest === test) // false
.bind并不修改原有函數(shù),它只會(huì)返回一個(gè)指定執(zhí)行上下文的新函數(shù)(boundTest和test并不相等),因此垃圾回收系統(tǒng)仍然需要回收你之前綁定的回調(diào)。
好的方案:在構(gòu)造函數(shù)(constructor)中bind handleClick仍然使用 .bind ,現(xiàn)在我們只要繞過(guò)每次渲染都要生成新的函數(shù)的問(wèn)題就可以了。我們可以通過(guò)只在構(gòu)造函數(shù)中綁定回調(diào)的上下問(wèn)來(lái)解決這個(gè)問(wèn)題,因?yàn)闃?gòu)造函數(shù)只會(huì)調(diào)用一次,而不是每次渲染都調(diào)用。這意味著我們沒(méi)有生成一堆函數(shù)然后讓垃圾回收系統(tǒng)清除它們。
class DankButton extends React.Component { constructor() { super() // Good Solution: Bind it in here! this.handleClick = this.handleClick.bind(this) } render() { return } handleClick() { this.logPhrase() } logPhrase() { console.log("such gnawledge") } }
很好,現(xiàn)在我們的函數(shù)被綁定到正確的上下文,而且不會(huì)在每次渲染的時(shí)候創(chuàng)建新的函數(shù)。
如果你使用的是React.createClass而不是ES6的classes,你就不會(huì)碰到這個(gè)問(wèn)題,createClass生成的組件會(huì)把它們的方法自動(dòng)綁定到組件的this,甚至是你傳遞給事件回調(diào)的函數(shù)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/90820.html
摘要:如果你使用實(shí)驗(yàn)性屬性初始化語(yǔ)法,你能用這方法來(lái)正確綁定回調(diào)函數(shù)的綁定這語(yǔ)法在中默認(rèn)支持。然而,如果這回調(diào)函數(shù)是作為一個(gè)傳遞到更下一級(jí)的組件中的時(shí)候,些組件可能會(huì)做一個(gè)額外的重新渲染。 下面是react官方文檔的個(gè)人翻譯,如有翻譯錯(cuò)誤,請(qǐng)多多指出原文地址:https://facebook.github.io/re... Handling events with React element...
摘要:點(diǎn)擊直達(dá)前文譯一個(gè)小時(shí)搭建一個(gè)全棧應(yīng)用框架上如果沒(méi)有,但還是要繼續(xù)學(xué)習(xí)本教程,可以到我的頁(yè)面下載代碼。從服務(wù)器返回隨機(jī)語(yǔ)言的每當(dāng)我們與服務(wù)器上的端點(diǎn)進(jìn)行通話時(shí),為了能夠請(qǐng)求一個(gè)隨機(jī)的歐洲語(yǔ)言,必須更改文件中的功能。 翻譯:瘋狂的技術(shù)宅原文標(biāo)題:Creating a full-stack web application with Python, NPM, Webpack and Reac...
摘要:點(diǎn)擊直達(dá)前文譯一個(gè)小時(shí)搭建一個(gè)全棧應(yīng)用框架上如果沒(méi)有,但還是要繼續(xù)學(xué)習(xí)本教程,可以到我的頁(yè)面下載代碼。從服務(wù)器返回隨機(jī)語(yǔ)言的每當(dāng)我們與服務(wù)器上的端點(diǎn)進(jìn)行通話時(shí),為了能夠請(qǐng)求一個(gè)隨機(jī)的歐洲語(yǔ)言,必須更改文件中的功能。 翻譯:瘋狂的技術(shù)宅原文標(biāo)題:Creating a full-stack web application with Python, NPM, Webpack and Reac...
摘要:搜索文本和多選框因?yàn)闀?huì)發(fā)生變化,且不能通過(guò)計(jì)算得出,所以是狀態(tài)。最后,過(guò)濾過(guò)的產(chǎn)品列表,可以通過(guò)原始產(chǎn)品列表搜索文本和多選框值計(jì)算出來(lái),因此它不是狀態(tài)。從傳入的回調(diào)函數(shù)會(huì)調(diào)用,從而更新組件。 在使用JavaScript開(kāi)發(fā)大型、快速的網(wǎng)頁(yè)應(yīng)用時(shí),React是我們的首選。在Facebook和Instagram,React很好地減少了我們的工作量。React最強(qiáng)大部分之一,是讓你在開(kāi)發(fā)應(yīng)用...
摘要:但是,你可能已經(jīng)注意到,當(dāng)你試圖通過(guò)指定依賴數(shù)組來(lái)優(yōu)化時(shí),可能會(huì)遇到帶有過(guò)時(shí)閉包的錯(cuò)誤。這是否意味著閉包是問(wèn)題所在我不這么認(rèn)為。到目前為止,我所看到的所有情況下,過(guò)時(shí)的閉包問(wèn)題都是由于錯(cuò)誤地假設(shè)函數(shù)不更改或總是相同而發(fā)生的。 原文鏈接:https://overreacted.io/how-ar... 在很長(zhǎng)一段時(shí)間內(nèi),標(biāo)準(zhǔn)答案是class components提供更多的特性(像sta...
閱讀 2745·2023-04-26 02:44
閱讀 9976·2021-11-22 14:44
閱讀 2185·2021-09-27 13:36
閱讀 2766·2021-09-08 10:43
閱讀 759·2019-08-30 15:56
閱讀 1451·2019-08-30 15:55
閱讀 2940·2019-08-28 18:12
閱讀 2898·2019-08-26 13:50