今天把第一個用在生產環境的React項目提交了,總算是在前端之路上邁出了另一步。
當初選擇這個技術棧的時候還是很忐忑的。一方面是傳聞中陡峭的學習曲線,另一方面也是框架大戰亂花迷人眼。不過這個小項目的完總算是讓我松了口氣,總算是證明了可行性。
回顧這幾個月的學習歷程,不得不承認人最大的敵人的是自己。如果當初我選擇了那個熟悉的開發環境,就絕對不會在幾個月后有如此的進步。主動放棄舒適區是種煎熬,好幾次我都在想: 如果用xxx的話很快就可以解決啊。好在忍住了回頭的沖動,硬著頭皮踩完坑,也理了解了許多之前從未思考過的問題。
React本身并不難,只要理解了props和state的區別就可以上手了。但React只解決了view的問題,要構建完整的項目還需要搭配其他組件,而React的生態環境才是真正復雜之處。SPA必須上router,于是得學react router,如果要配合redux還得考慮react redux router。state的管理是上flux還是redux呢?或者新鮮出爐的mobx也不錯?考慮國際化,又得從許多i18n庫中選一個。項目的工程化又是個難題,構建的webpack是標配了,還得熟悉各種插件。然后是測試,karma、jsdom、mocha、chi、jest、tape、enzyme……看到這里許多人都已經懵逼了,更別提去一一熟悉這些組件了。
我的學習方法是抓住本質:React is React,任何圍繞React構造的組件必然符合props和state的概念。熟悉了React,其他的組件自然也不會難理解,用到時再去看docs就可以了。在選擇組件的時候必須問兩個問題:這個組件解決了什么問題?我現在有這個問題嗎?回答不出來就不要因為cool而添加組件,必須牢記:多增加一個組件,就給項目多增加了一分復雜性,也就減少了一分項目的穩定性。
至于JFX和v-dom,我認為如果不是做理論研究的話,可以先將他們當作既成事實先用起來。當React相關代碼寫多了,這兩個看似怪異的東西的作用自然了然于胸。現在我再回過頭去看,v-dom其實就是一個表示dom結構的JS object,而JFX則是創建這個object的簡化語法。
React不再依賴event listener來同步dom更新,而是當state改變的時候就重新渲染整個dom。這簡化了state的同步,但重新渲染dom卻是十分影響性能的。比如有一個包含一百個子項的列表,當其中的一個改變時就得重新渲染這一百個子項,這樣的性能必然是無法接受的。于是v-dom的作用就體現出來了:React的render函數改變的只是v-dom的結構,再用v-dom和dom的狀態做比較,找出真正需要渲染的dom部分。于是一個既簡化了狀態同步,又相對高效的方式就這樣產生了。另外,由于增加了v-dom這個抽象層,React不再完全依附于Web。v-dom可以和各種原生平臺進行映射,我們就有了目前大熱的React native跨平臺解決方案。
這就是為什么React不再使用常見的template,而是由render函數返回一個v-dom,最后由framework來做算法比較最后更新dom或是其他native組件。一篇比較React和Angular的文章一針見血的指出了他們的本質區別:Angular使用JS來強化HTML,而React本身就是JS。
一個優秀的framework不僅要有優秀的特性,更應該引導開發者寫出優秀的代碼。這一點上,強調FP和組件分離的React無疑是成功的。組件化的概念從Web component標準就引入了,而首先將這個概念大規模用于生產環境就是React。我個人認為React在這一點上的意義遠勝過v-dom或JFX。而FP的好處我就不再復述了,從React這兩年的發展可以看出社區明顯的FP傾向,這或許會對JS標準的發展產生一定的影響。
我從來就不是一個框架原教旨主義者,我相信很快就會有更優秀的框架取代React,Web必將踏過React的尸體繼續前進。學習一個框架不僅是產出項目,更是開闊思維和成長技能。每一個優秀的框架都有可取之處,選擇任何一個公認優秀的東西都不會錯。
關鍵不是選擇,而是專注。