摘要:一個(gè)組件的顯示形態(tài)由多個(gè)狀態(tài)決定的情況非常常見(jiàn)。我們順利地消除了手動(dòng)的操作。非一般的暴力,因?yàn)槊看味贾匦聵?gòu)造新增刪除元素,會(huì)導(dǎo)致瀏覽器進(jìn)行大量的重排,嚴(yán)重影響性能。下一節(jié)小書(shū)前端組件化三抽象出公共組件類我們把這個(gè)通用模式抽離到一個(gè)類當(dāng)中。
React.js 小書(shū) Lesson3 - 前端組件化(二):優(yōu)化 DOM 操作
本文作者:胡子大哈
本文原文:http://huziketang.com/books/react/lesson3
轉(zhuǎn)載請(qǐng)注明出處,保留原文鏈接以及作者信息
在線閱讀:http://huziketang.com/books/react/
看看上一節(jié)前端組件化(一):從一個(gè)簡(jiǎn)單的例子講起我們的代碼,仔細(xì)留意一下 changeLikeText 函數(shù),這個(gè)函數(shù)包含了 DOM 操作,現(xiàn)在看起來(lái)比較簡(jiǎn)單,那是因?yàn)楝F(xiàn)在只有 isLiked 一個(gè)狀態(tài)。由于數(shù)據(jù)狀態(tài)改變會(huì)導(dǎo)致需要我們?nèi)ジ马?yè)面的內(nèi)容,所以假想一下,如果你的組件依賴了很多狀態(tài),那么你的組件基本全部都是 DOM 操作。
一個(gè)組件的顯示形態(tài)由多個(gè)狀態(tài)決定的情況非常常見(jiàn)。代碼中混雜著對(duì) DOM 的操作其實(shí)是一種不好的實(shí)踐,手動(dòng)管理數(shù)據(jù)和 DOM 之間的關(guān)系會(huì)導(dǎo)致代碼可維護(hù)性變差、容易出錯(cuò)。所以我們的例子這里還有優(yōu)化的空間:如何盡量減少這種手動(dòng) DOM 操作?
狀態(tài)改變 -> 構(gòu)建新的 DOM 元素更新頁(yè)面這里要提出的一種解決方案:一旦狀態(tài)發(fā)生改變,就重新調(diào)用 render 方法,構(gòu)建一個(gè)新的 DOM 元素。這樣做的好處是什么呢?好處就是你可以在 render 方法里面使用最新的 this.state 來(lái)構(gòu)造不同 HTML 結(jié)構(gòu)的字符串,并且通過(guò)這個(gè)字符串構(gòu)造不同的 DOM 元素。頁(yè)面就更新了!聽(tīng)起來(lái)有點(diǎn)繞,看看代碼怎么寫(xiě),修改原來(lái)的代碼為:
class LikeButton { constructor () { this.state = { isLiked: false } } setState (state) { this.state = state this.el = this.render() } changeLikeText () { this.setState({ isLiked: !this.state.isLiked }) } render () { this.el = createDOMFromString(` `) this.el.addEventListener("click", this.changeLikeText.bind(this), false) return this.el } }
其實(shí)只是改了幾個(gè)小地方:
render 函數(shù)里面的 HTML 字符串會(huì)根據(jù) this.state 不同而不同(這里是用了 ES6 的模版字符串,做這種事情很方便)。
新增一個(gè) setState 函數(shù),這個(gè)函數(shù)接受一個(gè)對(duì)象作為參數(shù);它會(huì)設(shè)置實(shí)例的 state,然后重新調(diào)用一下 render 方法。
當(dāng)用戶點(diǎn)擊按鈕的時(shí)候, changeLikeText 會(huì)構(gòu)建新的 state 對(duì)象,這個(gè)新的 state ,傳入 setState 函數(shù)當(dāng)中。
這樣的結(jié)果就是,用戶每次點(diǎn)擊,changeLikeText 都會(huì)調(diào)用改變組件狀態(tài)然后調(diào)用 setState ;setState 會(huì)調(diào)用 render ,render 方法會(huì)根據(jù) state 的不同重新構(gòu)建不同的 DOM 元素。
也就是說(shuō),你只要調(diào)用 setState,組件就會(huì)重新渲染。我們順利地消除了手動(dòng)的 DOM 操作。
重新插入新的 DOM 元素上面的改進(jìn)不會(huì)有什么效果,因?yàn)槟阕屑?xì)看一下就會(huì)發(fā)現(xiàn),其實(shí)重新渲染的 DOM 元素并沒(méi)有插入到頁(yè)面當(dāng)中。所以在這個(gè)組件外面,你需要知道這個(gè)組件發(fā)生了改變,并且把新的 DOM 元素更新到頁(yè)面當(dāng)中。
重新修改一下 setState 方法:
... setState (state) { const oldEl = this.el this.state = state this.el = this.render() if (this.onStateChange) this.onStateChange(oldEl, this.el) } ...
使用這個(gè)組件的時(shí)候:
const likeButton = new LikeButton() wrapper.appendChild(likeButton.render()) // 第一次插入 DOM 元素 component.onStateChange = (oldEl, newEl) => { wrapper.insertBefore(newEl, oldEl) // 插入新的元素 wrapper.removeChild(oldEl) // 刪除舊的元素 }
這里每次 setState 都會(huì)調(diào)用 onStateChange 方法,而這個(gè)方法是實(shí)例化以后時(shí)候被設(shè)置的,所以你可以自定義 onStateChange 的行為。這里做的事是,每當(dāng) setState 中構(gòu)造完新的 DOM 元素以后,就會(huì)通過(guò) onStateChange 告知外部插入新的 DOM 元素,然后刪除舊的元素,頁(yè)面就更新了。這里已經(jīng)做到了進(jìn)一步的優(yōu)化了:現(xiàn)在不需要再手動(dòng)更新頁(yè)面了。
非一般的暴力,因?yàn)槊看?setState 都重新構(gòu)造、新增、刪除 DOM 元素,會(huì)導(dǎo)致瀏覽器進(jìn)行大量的重排,嚴(yán)重影響性能。不過(guò)沒(méi)有關(guān)系,這種暴力行為可以被一種叫 Virtual-DOM 的策略規(guī)避掉,但這不是本文所討論的范圍。
這個(gè)版本的點(diǎn)贊功能很不錯(cuò),我可以繼續(xù)往上面加功能,而且還不需要手動(dòng)操作DOM。但是有一個(gè)不好的地方,如果我要重新另外做一個(gè)新組件,譬如說(shuō)評(píng)論組件,那么里面的這些 setState 方法要重新寫(xiě)一遍,其實(shí)這些東西都可以抽出來(lái),變成一個(gè)通用的模式。
下一節(jié)《React.js 小書(shū) Lesson4 - 前端組件化(三):抽象出公共組件類》我們把這個(gè)通用模式抽離到一個(gè)類當(dāng)中。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/89654.html
摘要:一個(gè)組件的顯示形態(tài)和行為有可能是由某些數(shù)據(jù)決定的。一個(gè)簡(jiǎn)單的點(diǎn)贊功能我們會(huì)從一個(gè)簡(jiǎn)單的點(diǎn)贊功能講起。我們需要結(jié)構(gòu),準(zhǔn)確地來(lái)說(shuō)我們需要這個(gè)點(diǎn)贊功能的字符串表示的結(jié)構(gòu)。下一節(jié)小書(shū)前端組件化二優(yōu)化操作中我們繼續(xù)優(yōu)化這個(gè)例子,讓它更加通用。 React.js 小書(shū) Lesson1-2 - 前端組件化(一):從一個(gè)簡(jiǎn)單的例子講起 本文作者:胡子大哈本文原文:http://huziketang....
摘要:因?yàn)楣ぷ髦幸恢痹谑褂茫惨恢币詠?lái)想總結(jié)一下自己關(guān)于的一些知識(shí)經(jīng)驗(yàn)。于是把一些想法慢慢整理書(shū)寫(xiě)下來(lái),做成一本開(kāi)源免費(fèi)專業(yè)簡(jiǎn)單的入門級(jí)別的小書(shū),提供給社區(qū)。本書(shū)的后續(xù)可能會(huì)做成視頻版本,敬請(qǐng)期待。本作品采用署名禁止演繹國(guó)際許可協(xié)議進(jìn)行許可 React.js 小書(shū) 本文作者:胡子大哈本文原文:React.js 小書(shū) 轉(zhuǎn)載請(qǐng)注明出處,保留原文鏈接以及作者信息 在線閱讀:http://huzi...
摘要:最后抽離出來(lái)了一個(gè)類,可以幫助我們更好的做組件化。一個(gè)組件有自己的顯示形態(tài)上面的結(jié)構(gòu)和內(nèi)容行為,組件的顯示形態(tài)和行為可以由數(shù)據(jù)狀態(tài)和配置參數(shù)共同決定。接下來(lái)我們開(kāi)始正式進(jìn)入主題,開(kāi)始正式介紹。下一節(jié)鏈接直達(dá)小書(shū)基本環(huán)境安裝 React.js 小書(shū) Lesson4 - 前端組件化(三):抽象出公共組件類 本文作者:胡子大哈本文原文:http://huziketang.com/books...
摘要:所以對(duì)于組件更新階段的組件生命周期,我們簡(jiǎn)單提及并且提供一些資料給大家。這里為了知識(shí)的完整,補(bǔ)充關(guān)于更新階段的組件生命周期你可以通過(guò)這個(gè)方法控制組件是否重新渲染。大家對(duì)這更新階段的生命周期比較感興趣的話可以查看官網(wǎng)文檔。 React.js 小書(shū) Lesson20 - 更新階段的組件生命周期 本文作者:胡子大哈本文原文:http://huziketang.com/books/react...
摘要:一般來(lái)說(shuō),的值可以直接后臺(tái)數(shù)據(jù)返回的,因?yàn)楹笈_(tái)的都是唯一的。下一節(jié)中我們將介紹小書(shū)實(shí)戰(zhàn)分析評(píng)論功能一。 React.js 小書(shū) Lesson13 - 渲染列表數(shù)據(jù) 本文作者:胡子大哈本文原文:http://huziketang.com/books/react/lesson13 轉(zhuǎn)載請(qǐng)注明出處,保留原文鏈接以及作者信息 在線閱讀:http://huziketang.com/books/...
閱讀 1811·2021-10-09 09:44
閱讀 3382·2021-09-28 09:35
閱讀 1372·2021-09-01 10:31
閱讀 1658·2019-08-30 15:55
閱讀 2697·2019-08-30 15:54
閱讀 923·2019-08-29 17:07
閱讀 1372·2019-08-29 15:04
閱讀 2001·2019-08-26 13:56