React's JSX: 硬幣的反面

React 剛發布的時候,很多人才看了一眼,然后就有點接受不了。JavaScript 里的那些尖括號是干啥用的?!淦,說好的分離呢?Facebook 到底有沒有從社區學到教訓?

跟很多人一樣,我一開始對于 React's JSX 的這種做法到底有沒有效,也是將信將疑,這點還是可以肯定的。但現在我已經愛上 JSX 了,每當我向新人推薦它,都感覺像在炫耀自己實際長得一點都不好看的兒子。

這里有一張作者兒子的照片,還是很可愛的。(我是圖片)

除了標簽和 JavaScript 混寫外,我知道 JSX 也不是一個徹底的方案。實際上,它就是硬幣的另一面,跟事物發展到某種程度就會出現的東西一樣。想知道為什么,搬好椅子,我要開始講(zhuang)課(bi)了。

第一階段:沒什么存在感的 JavaScript (Unobtrusive JavaScript

還記得過去 jQuery 的大好時光嗎?到處都是選擇器和 DOM 操作。這時,標簽是單純的標簽,腳本是單純的腳本。嗯,這感覺還不錯。

我們會像這樣寫標簽:

<a class="hide">click me to hide</a>

像這樣寫腳本:

$('.hide').click(function() {$(this).hide();})

這樣就可以下班了?并沒有。

似乎是個不錯的方案呢~ 我們的標簽很純粹!問題隨之而來,我怎么在腳本里找到關于這個標簽的所有邏輯呢?答:通讀腳本,一行不漏。在某些極端條件下,你都不能隨便動 DOM tree 結構,可能導致某些選擇器失效,除非你通讀代碼。You see? 分離沒有想象中的簡單。腳本和標簽的確是在各自的文件里,而實際上它們已經緊緊相擁在一起。新的維護人員必須看懂以前的人寫的所有代碼,否則容易炸(the guy who wrote these codes was gone ...)

嚴格遵守分離原則,帶來的只有痛苦的維護和 debug 體驗。每次你想改內容,都得擔心會不會又有哪個選擇器失效?;蛟S從一開始就走錯了方向,放下對分離原則的偏執,或許能更愉快地開發?

第二階段:雙向綁定

當前端們在 Knockout 和 Angular 里第一次見到雙向綁定,好比約伯受盡千辛萬苦見到耶穌。我們之中很多人毫不猶豫立刻拋棄了對分離原則宗教般的信仰,投奔聲明式綁定的懷抱(直接在標簽里聲明:v-if v-else ng-for ......)。數據層變,UI 也跟著變;UI 變,數據層也跟著變。很干凈,很明了。

每個庫或框架都有它自己用來實現雙向綁定的方式,但本質上做的都是同一件事情。先看看下面這幾個來自比較流行的框架里的遍歷數組的例子:

// Angular

<div ng-repeat="user in users">

// Ember

{{#each user in users}}

// Knockout

data-bind="foreach: users"

這里發生了一些有趣的事。很少人意識到這個根本問題:我們正努力地把腳本嵌進標簽里,而不是分離。這幾個例子實現的都是同一件事情:通過添加額外的屬性來增強原生標簽,借由腳本來解析實現?,F在,我們能愉快地把腳本和標簽以這種方式寫在一起,是時候介紹 React: 硬幣的反面了。

第三階段:JSX

React 的 JSX 不夠徹底,它也不過是這個想法所產生的成果之一:業界達成共識,標簽和腳本應該放在一起。誠然,我們的宣傳不夠廣泛。但只要你用過 Angular,Knockout,Ember 就能明白這個新方向了。像我上面所演示的,數據綁定式的標簽寫法就是不斷地把腳本寫到標簽里。既然已經選擇腳本標簽混寫,為什么還要加到 HTML 這種不嚴謹、松散、軟弱無力的語言里呢?從一開始,瀏覽器對 HTML 的解析就很寬容,也不嚴謹。那么 HTML 還有實現聲明數據綁定,變量遍歷,邏輯判斷的嚴謹的結構基礎嗎?

Facebook 認識到這點,JavaScript 更有邏輯,也是一門不錯的語言來解決這兩者混寫時遇到的問題。這時候,轉變再次發生:

Angular,Ember 和 Knockout 把 JavaScript 放到 HTML 里,React 把 HTML 放到 JavaScript 里

這一舉措帶來的益處是多方面的,直到你用上了 React 和 JSX 很久之后才能深刻體會到。React 的 JSX 完勝階段二里提到的所有技術,因為以下理由:

編譯時報錯

當你在 HTML 里拼錯,你根本不知道哪里有問題。很多情況下,就是個被忽略了的運行時錯誤。例如:用 Angular 的時候,你把 ng-repeat 寫成 n-repeat,頁面什么都沒發生;用 Knockout 時,把 data-bind 寫成 data-bnd 也一樣。它們能跑起來,但不會報錯。

相反,如果你在 JSX 里拼錯一個字母,它就編譯不了。忘記關閉 li 標簽?你難道不希望在寫 HTML 的時候獲得更豐富的反饋?

JSX 讓這種必要的反饋成為了現實!這個舉措的重要性怎么強調也不過分。快速反饋能大幅提升生產力。像我在 Clean Code 課上講到的:越快報錯的方案,就是越好的方案。

解放 JavaScript 的所有潛能

把標簽和腳本寫在一起,意味著你能夠享受 JavaScript 帶來的所有便利,以及更嚴謹的標簽,不像以 HTML 為基礎的框架,類似Angular(應該指 1.0 版本)和 Knockout 那樣只提供部分功能。

客戶端框架(Angular 1 Knockout ...)不應該需要學習額外語法來循環聲明以及條件判斷。(雖然語法形式都類似)

React 避免了這點,而階段二中提到的技術,各有各的語法形式。與此相反,JSX 看起來跟 HTML 挺像的,除了它用的是原生的 JavaScript 寫法(剛開始看起來,確實有點不適應)。在一個以 JavaScript 為基礎的生態圈里,不用學全新語法確實不錯。

JSX,很多 IDE 已經有智能提示。以 HTML 為基礎的很多框架還不能做到這一點

最后

JSX 的產生并不是無中生有,它是自然過程的一個階段,所以無法逃避

(老文渣翻)

原文地址:https://medium.com/@housecor/react-s-jsx-the-other-side-of-the-coin-2ace7ab62b98

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 前端這幾年的技術發展很快,細分下來,主要可以分成四個方面: 開發語言技術,主要是ES6&7,coffeescrip...
    Su丶_33b0閱讀 15,159評論 3 46
  • Gitbook Repo 撰寫本文的時候筆者閱讀了以下文章,不可避免的會借鑒或者引用其中的一些觀點與文字,若有冒犯...
    王下邀月熊閱讀 1,097評論 1 9
  • Vue對比其他框架 這個頁面無疑是最難編寫的,但我們認為它也是非常重要的?;蛟S你曾遇到了一些問題并且已經用其他的框...
    伊滴墨閱讀 1,821評論 0 15
  • 以下內容是我在學習和研究React時,對React的特性、重點和注意事項的提取、精練和總結,可以做為React特性...
    科研者閱讀 8,282評論 2 21
  • 最近被大家對86版《西游記》的導演楊潔女士不幸離世的各種緬懷刷了屏,我想這些鋪天蓋地的悼念不僅說明了大家對楊潔導演...
    漢尼拔絲蘋果9閱讀 250評論 0 0