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