如何編寫漂亮的 React 代碼?(react代碼規(guī)范)
React 代碼很難看。我不是在談?wù)撨@個框架的任何技術(shù)特性;我說的是直觀的美學,代碼在我屏幕上的樣子,以及它所喚起的感覺。
代碼美學通常并不是開發(fā)人員關(guān)注的問題。我們要操心更重要的問題。美學是主觀的,很難衡量,追求它的好處也并不明確。你很少會看到一個開發(fā)人員舉手在站例會上告訴他們的同事他們對代碼在屏幕上的樣子不滿意。我不確定是否有人會這么做,但我的看法有所不同。
我是在從事一個副業(yè)項目時,開始考慮 React 的美觀問題的。作為大多數(shù)以編碼為職業(yè)和愛好的程序員,工作和休閑之間的區(qū)別是由你所享受到的快樂所決定的。當然,我們的職業(yè)生涯目標是讓這兩者一致,盡管有時候這兩者是一致的,但是當這兩者不一致時,你仍然希望你的“編碼放松”時間盡可能地愉悅。
當然,如果出于某種原因,React 對我來說是不愉快的,而我想要花時間編寫代碼來獲得樂趣,那么最明顯的做法就是不要使用 React。而我大多數(shù)時間就是不用 React 的。但是,眾所周知,編碼是多方面的:你有代碼、工件、你向計算機輸入的符號行,但你也有代碼結(jié)果,它的輸出,你用編程語言表達的想法的現(xiàn)實意義??梢詮奈业拇a與現(xiàn)實世界的交互中獲得同等甚至更大的樂趣,我對此比較在乎。
結(jié)果是,盡管有時我發(fā)現(xiàn)一種編程語言、框架、工具不太好看或不好用,但我需要它來在合理的時間內(nèi)讓我的代碼描述現(xiàn)實的某件事。也許這就是大型社區(qū)圍繞這些工具創(chuàng)建東西的原因,或者其它一些技術(shù)特性。不管什么原因,我的編碼作為業(yè)余愛好的時間很少,而且盡管我想讓它變得愉快,但我也希望充分利用這些時間,這意味著使用不總是符合我的審美標準的東西。React 就是這樣的東西。
有一天,當我思考這個話題的時候,突然想到一個問題:我能在保持高生產(chǎn)力的同時,寫出既美觀又令人愉悅的 React 代碼嗎?我知道在其它編程語言和框架中,這個問題有非常有價值的答案。所有那些方法都會有不同程序的相同權(quán)衡,例如學習難度、能從 React 生態(tài)系統(tǒng)獲益的多少、圍繞它的工具如何等等。所有這些權(quán)衡都要根據(jù)項目的目標進行不同的衡量。
我對這個問題的答案通常是一些非 React 的其它東西。但每隔一段時間,你會比較每一個權(quán)衡;你從不同的角度看待你的項目;你試著重新考慮你設(shè)想的特性和你的需求;最后,React 會是你的答案??紤]到這些情況,我將原來的問題重新設(shè)定為:“在保持 React 代碼不變的同時,我還能在多大程度上使 React 代碼更好看?”
“在保持 React 代碼不變的同時,我還能在多大程度上使 React 代碼更好看?”
為了開始回答這問題,我創(chuàng)建了一個 Create React App 項目,使用了一些簡單的 React 代碼作為參考。我希望它有一點兒抽象,足夠簡單,這樣就不會妨礙測試不同的東西。我選擇了官方的 React 教程代碼,你可以在這里找到。
聚焦這段代碼的最簡單的 React 組件,Square 組件,我們看到如下代碼:
function Square(props) { return ( <button className=”square” onClick={props.onClick}> {props.value} </button> );}
而這就是比較主觀的一點:我對這段代碼很不滿意。我不是在討論這段代碼的技術(shù)屬性。當我說它難看的時候,我只是在試圖表達它在我心中喚起的一套感覺,而這在很大程度上是基于我對世界的總體體驗,特別是編程。從這個角度來看,第一個讓我抓狂的問題是 JSX。
自從 JSX 推出以來,它已經(jīng)被討論了很多,但是為了闡明我的觀點,我將快速說明一下。JSX 很混亂,但它也是一種現(xiàn)實產(chǎn)物。它源于前端技術(shù)的自然演變,從一開始就有某種形式的 XML 語言來定義標簽。不同之處在于,JSX 通常位于 JavaScript 代碼中。
與口語語言進行粗略的類比,JSX 就好像某一特定語言的使用者開始使用其它語言的一整套單詞和短語來表達自己。例如,當一個特定的主題是某一特定文化所固有的時候,這種情況就經(jīng)常發(fā)生。當文化之外的人,說不同語言的人,面對表達關(guān)于這個主題的想法的挑戰(zhàn)時,他們通常會缺乏詞匯來處理這個問題,重復使用那些“產(chǎn)生”這個話題的人所說的語言來解決這個問題。語言純粹主義者很快就會生氣,指出你怎么能不需要外來詞匯就可以說那些話題。但人們?nèi)匀粫褂眠@些詞,其中一些詞最終會被納入官方語言。JSX 誕生于 JavaScript 開發(fā)人員對于表達 UI 標簽的需要。
繼續(xù)上面語言使用者的類比,一些靈魂將語言用于審美目的和自我表達。詩人和文學作家通常就是這樣。他們?nèi)绾慰创庹Z單詞?好吧,他們毫無疑問會有不同的看法。他們的觀點與我這里的觀點類似,因為這不僅從語言表達思想的能力來看待語言,同時還從美學角度考慮。從這個角度來看,JSX 的使用是不必要的:它增加了噪音,并且對于它表達思想沒有幫助。
所有這些都是說,我朝著一種更愉快的方式編寫 React 的第一步就是擺脫 JSX。
無 JSX 版本的 button 組件如下所示:
const e = React.createElement;function Square({ onClick, value }) { return e(‘button’, { className: ‘square’, onClick }, value);}
代碼的一致性和簡潔性帶來了實質(zhì)上的美學提升。而且我們可以在無 JSX 路上走得更遠。我遠不是第一個討論是否采用 JSX 的人。對于 JSX 的厭惡可能和 JSX 本身一樣古老。我打賭 JSX 最初的團隊至少有人說過這是不必要的。你會發(fā)現(xiàn)大量關(guān)于 JSX 糟糕的原因以及不使用 JSX 的好處的閱讀資料。令人高興的是,你也可以找到技術(shù)上的替代品。一個突出的例子是 Hyperscript,它是 React 團隊 在他們的文檔中 推薦的。這是一個簡單的工具,可以幫助你使用 JavaScript 構(gòu)建超文本。它的 React 版本帶來了比createElement 更吸引人的 API。我決定將它與一個稱作hyperscript-helpers的小工具庫一起使用試試,我發(fā)現(xiàn)這些工具對代碼美觀的貢獻相當不錯:
function Square({ onClick, value }) { return button({ className: ‘square’, onClick }, value);}
取代 JSX 是帕累托原則在 React 代碼美觀方面的應用。省力,效果好。如果想要更漂亮的 React 代碼,每個人都應該采取行動。繼續(xù)探索如何在框架領(lǐng)域美化 React 代碼,我發(fā)現(xiàn)了一個死胡同。雖然我可以探索一些設(shè)計模式和簡單的慣例,但它們需要根據(jù)具體情況評估它們的技術(shù)含義,而我正在尋找更通用的方法。因此,下一步需要在 JavaScript 層探索。
JavaScript 是一種非常靈活的語言,這是一把雙刃劍。這也可以從美學角度來探索。有許多不同的方法可以編寫有效的代碼,但會有明顯的風格差異和技術(shù)意義。許多工具可以幫助你自定義和強制你所選擇風格,在這些工具中,我最喜歡:StandardJS。StandardJS 是一個用于自動將一系列合理的編碼樣式選擇應用到你的代碼的一個工具。在這些選擇中最具有美學意義的一點是去掉了分號。
我發(fā)現(xiàn),分號在 JS 代碼中是一種不必要的噪音,我很樂意冒險不使用它們。在我將 StandardJS 合并到我的參考示例后,是下面這樣:
function Square ({ onClick, value }) { return button({ className: ‘square’, onClick }, value)}
現(xiàn)在就 JavaScript 代碼而言,這是我所能得到的最好的代碼了?;仡櫟侥壳盀橹刮宜龅臇|西,一切看起來還都不錯。這些更改實現(xiàn)很簡單,可以很容易地集成到我的默認副業(yè)項目的 React 配置中。另一方面,這在美學上與我在其它不同語言中的體驗仍然相去甚遠。我已經(jīng)討論過其它語言的情況,重點是我想在 JS 世界中使用 React。除非有什么東西能給 JavaScript 增添一些優(yōu)雅的光彩,同時又保持 JavaScript 的樣子,否則很難達到我設(shè)定的界限。
“就像 JavaScript 一樣?!碑斣噲D發(fā)揮我的創(chuàng)造力去尋找不同的可能性時,這句話讓我回到了十年前。我正在學習 Web 開發(fā),而且剛剛碰到 Ruby on Rails。那時,Rails 在發(fā)布時通常會內(nèi)置附帶一種不同類型的 JavaScript,稱作 CoffeeScript。CoffeeScript 有一條黃金法則:“這只是 JavaScript?!本褪悄菢樱珻offeeScript 可以滿足我的標準,因此我決定看看這個項目進展如何并嘗試一下。
我知道,自從 ES5 以來,CoffeeScript 的一些好的特性被整合到 JS 標準中,因此從技術(shù)上講,人們采用 CoffeeScript 的理由更少了。隨著編譯器的出現(xiàn),使得每個人都可以使用甚至還不是標準的 JS 特性,即使是不得不支持舊瀏覽器的開發(fā)人員現(xiàn)在也可以從最新的語言特性中受益。這使得 CoffeeScript 的流行程度大不如前。但是我的興趣不是技術(shù)性的。我想找到一個令人愉快的美學方案,使得我可以編寫看起來不錯的 React 代碼,同時還是 JavaScript,而不需要學習一種新語言或者框架。
從文檔來看,CoffeeScript 與 JavaScript 非常接近,我可以忽略學習曲線,而且它在美學方面給代碼帶來了顯著改進。我一直懷疑它是否還在維護,事實證明它確實還在維護。其最新版本在今年初完成。它的最新主版本包含了新的 JS 特性,甚至支持 JSX。因此,我決定將它集成到我的示例項目中。為此,我不得不將我的 Creact React App 配置彈出,這樣我就可以為 CoffeeScript 增加一個 Webpack 加載器。除此之外,轉(zhuǎn)換非常簡單。
這就是設(shè)計的 Button 組件最終代碼的樣子:
Square = ({ onClick, value }) -> button ‘.square’, { onClick }, value
如果你對整個代碼最終的樣子感到好奇,你可以在這里找到它。
在美學方面,我認為這個代碼對于我最初的代碼是巨大的進步。語法簡潔,看起來干凈。
關(guān)于美的追求,更少就是更美,人們已經(jīng)說了很多。我很認同這一點。結(jié)果發(fā)現(xiàn),我的美觀探索基本上就是用更少的 React 代碼表達思想。CoffeeScript 帶來的卓越改進——也是其它語言使用的方式——就是去掉無意義的標記。這種認識在最后會很明顯,但最初不怎么明顯。它的目的是總體上增強 less 的力量。
從務(wù)實的角度來看,乍一看,采用這種風格似乎不會影響生產(chǎn)力。CoffeeScript 推出已經(jīng)有一段時間了,而且我期望它有一些像樣的工具。我在做這個快速實驗時沒有感到意外。不過,有一件事讓我無法完全采用它:那就是與 TypeScript 一起使用的能力。我知道如何讓它起效,但是我決定在這一點上停止探索。不管怎樣,如果你喜歡這個情景,就會有興趣采用相似的方案,并且會對它如何與 TypeScript 一起工作感到好奇,可以留言告訴我。
感謝您的閱讀。
總結(jié): 從代碼美學的角度來看,Hyperscript 和 CoffeeScript 的結(jié)合是編寫漂亮的 React 代碼的一種很好的方式。
作者介紹
Vinicius Andrade,學會編碼,學會思考,學會行動,學會等待——在 https://vicnicius.com 記錄所思所感。
原文鏈接:
https://medium.com/javascript-in-plain-english/writing-beautiful-react-code-using-a-good-old-mate-ca1450c0dc06
延伸閱讀:
被開除的蘋果前高管:我眼中 40 年前的蘋果-InfoQ
關(guān)注我并轉(zhuǎn)發(fā)此篇文章,即可獲得學習資料~若想了解更多,也可移步InfoQ官網(wǎng),獲取InfoQ最新資訊~