原文地址:medium.freecodecamp.org/psst-heres-…
你是否使用 React 來構建使用者介面?好吧,我也是。接下來你會了解為什麼要使用 ReasonML 來寫 React 應用。
React 是構建使用者介面的一種很酷的手段,我們該如何讓這個過程變得更酷呢?
為了回答這個問題,我們首先要了解 React 作為 JavaScript 庫的主要問題是什麼?
React 最初並不是為了 JavaScript 而開發的
如果你有深入瞭解 React,你會發現它的一些主要原則對 JavaScript 來說是陌生的,讓我們就 不可變性,函數語言程式設計原則,特別是型別系統來討論一下這個問題。
- 不可變性是 React 的核心原則,你肯定不想要改變 props 或者 state,因為你一旦改變了它們,你將面對不可預期的後果。在 JavaScript 中,沒有開箱即用的不可變性,我們通過約定保持資料的不可變性,或者使用 immutableJS 這樣的庫來輔助我們達到目的。
- React 基於函數語言程式設計的原理,因為 React 應用是函式的組合。儘管 JavaScript 具有一些函數語言程式設計的特性,例如頭等函式(是指在程式設計語言中,函式被當作頭等公民),但是它並不是一個函數語言程式設計語言。當我們想要寫一些優雅的宣告式程式碼的時候,我們還需要像 Lodash/fp 或者 Ramda 的庫的輔助。
- 那麼型別系統呢?我們使用React 中的 PropTypes來約定資料型別,因為 JavaScript 本身不是靜態型別語言。為了使用強大的靜態型別檢查,我們仍然還是需要 Flow 和 TypeScript 這樣的庫來輔助。
有沒有什麼語言比 JavaScript 更適合用來寫 React 呢?
幸運的是,我們有 ReasonML。
因為 ReasonML 是基於 OCaml 這樣的函數語言程式設計語言,所以 ReasonML 內建了不可變性這樣的語言特性,順理成章地,我們有了開箱即用的不可變性。Reason還為我們提供了一個強大的型別系統。
Reason 相容了 React 的核心原則。Reason
Reason 不是一種新語言。它是 OCaml 的另一種類似 JavaScript 的語法和工具鏈,一種已經存在了20多年的函數語言程式設計語言。Reason是由已經在專案中使用OCaml的Facebook開發人員建立的(Flow,Infer)。
具有類 C 語法的 Reason 使得 OCaml 更容易被 JavaScript或Java等主流語言的使用者所接受。 它為您提供了更好的文件(與OCaml相比)和不斷增長的社群。 此外,它還可以更輕鬆地與現有的JavaScript程式碼庫整合。
Reason 語言基於 OCaml 語言,Reason與OCaml具有相同的語義 - 只有語法不同。 這意味著您可以使用Reason的類似JavaScript的語法編寫OCaml。 因此,您可以利用OCaml的強大功能,例如強大的型別系統和模式匹配。
我們來看一下Reason的語法示例。
let fizzbuzz = (i) =>
switch (i mod 3, i mod 5) {
| (0, 0) => "FizzBuzz"
| (0, _) => "Fizz"
| (_, 0) => "Buzz"
| _ => string_of_int(i)
};
for (i in 1 to 100) {
Js.log(fizzbuzz(i))
};
複製程式碼
雖然我們在這個例子中使用了模式匹配,但它仍然非常類似於JavaScript,對吧? 但是,瀏覽器唯一可用的語言仍然是JavaScript,這意味著我們需要編譯它。
BuckleScript
Reason的強大功能之一是BuckleScript編譯器,它可以獲取您的Reason程式碼,並將其編譯為可讀且高效能的JavaScript,並消除了極大的程式碼。如果你在一個不是每個人都熟悉 Reason 的團隊工作,你會感激可讀性,因為他們仍然能夠閱讀編譯後的 JavaScript 程式碼。 因為 Reason 與 JavaScript 的有很大的相似性,所以一些 Reason 的程式碼根本不需要由編譯器進行更改。 因此,您可以享受靜態型別語言帶來的好處,而無需更改任何程式碼。
let add = (a, b) => a + b;
add(6, 9);
複製程式碼
上面這段程式碼在 Reason 中和 JavaScript 中都有效。
BuckleScript 附帶了四個庫:名為 Belt 的標準庫( OCaml 標準庫不足),以及與 JavaScript,Node.js和 DOM API 的繫結。
由於 BuckleScript 基於 OCaml 編譯器,因此您將獲得比 Babel 快得多的快速編譯,並且比 TypeScript 快幾倍。
讓我們編譯我們在Reason中編寫的FizzBuzz演算法。
如您所見,生成的 JavaScript 程式碼非常易讀,就像是由 JavaScript 開發人員編寫的。 Reason 不僅編譯為 JavaScript,還編譯為原生語言和位元組碼。 因此,您可以使用 Reason 語法編寫單個應用程式,並能夠在 MacOS,Android 和 iOS 手機上的瀏覽器中執行它。 Jared Forsyth 有一款叫做 Gravitron 的遊戲,它是用 Reason 編寫的,它可以在我剛剛提到的所有平臺上執行。
JavaScript 互操作
BuckleScript 還為我們提供了 JavaScript 互操作性。 您不僅可以將自己正在執行的 JavaScript 程式碼貼上到 Reason 程式碼庫中,還可以將 Reason 程式碼與該 JavaScript 程式碼進行互動。 這意味著您可以輕鬆地將 Reason 程式碼整合到現有的 JavaScript 程式碼庫中。 此外,您可以在 Reason 程式碼中使用 NPM 生態系統中的所有 JavaScript 包。 例如,您可以在單個專案中將 Flow,TypeScript 和 Reason 組合在一起。
然而,事情並非那麼簡單。 要在Reason中使用JavaScript庫或程式碼,您需要首先通過Reason繫結將其移植到Reason。換句話說,您需要型別為您的無型別JavaScript程式碼,以便能夠利用Reason的強型別系統。
每當您需要在Reason程式碼中使用 JavaScript 庫時,請通過瀏覽 Reason Package Index(Redex)資料庫來檢查庫是否已移植到 Reason。 它是一個網站,它使用 Reason 繫結聚合使用 Reason 和 JavaScript 庫編寫的不同庫和工具。
如果您在那裡找到了庫,則可以將其作為依賴項安裝,並在 Reason 應用程式中使用它。 但是,如果您沒有找到您的庫,則需要自己編寫Reason繫結。 如果您剛開始使用 Reason ,請記住,編寫繫結不是您想要開始的事情,因為它是 Reason 生態系統中更具挑戰性的事情之一。
幸運的是,我正在寫一篇關於編寫Reason繫結的帖子,敬請期待! 當您需要JavaScript庫中的某些功能時,您不需要為整個庫編寫Reason繫結。 您只能對需要使用的功能或元件執行此操作。
ReasonReact
本文是關於在 Reason 中的 React,感謝 ReasonReact 庫可以做到這一點。
也許你現在在想“我仍然不知道為什麼我應該在 Reason 中使用 React。” 我們已經提到過這樣做的主要原因 - Reason 比 JavaScript 更相容 React。
為什麼它更相容?因為 React 是為 Reason 開發的,或者更準確地說是為 OCaml 開發的。
React 的第一個原型是由 Facebook 開發的,用 OCaml 的堂兄標準元語言(StandardML)編寫。 然後,它被轉移到 OCaml。 React 也被轉錄為 JavaScript。
這是因為整個網路都在使用 JavaScript,並且說“現在我們將在 OCaml 中構建 UI”並不是很明智。它確實有效--React in JavaScript 已被廣泛採用。
因此,我們習慣將 React 用作 JavaScript 庫。React 與其他庫和語言 - Elm,Redux,Recompose,Ramda和PureScript - 在JavaScript中流行的函數語言程式設計。 隨著Flow和TypeScript的興起,靜態型別也變得流行。 因此,具有靜態型別的函數語言程式設計正規化成為前端世界的主流。
2016年,Bloomberg開發並開源了BuckleScript,這是一種將OCaml轉換為JavaScript的編譯器。
這使他們能夠使用OCaml的強型別系統在前端編寫安全程式碼。 他們採用優化且極其快速的OCaml編譯器並交換其後端生成本機程式碼,用於生成JavaScript。
函數語言程式設計的普及以及BuckleScript的釋出為Facebook提供了理想的環境,使其能夠回到最初以ML語言編寫的React的最初想法。
他們採用了OCaml語義和JavaScript語法,並建立了Reason。 他們還在React - ReasonReact庫周圍建立了Reason包裝器,並具有其他功能,例如在有狀態元件中封裝Redux原則。 通過這樣做,他們將React歸還其原始根源。
React in Reason的能量
當React進入JavaScript時,我們通過引入各種庫和工具來調整JavaScript以滿足React的需求。
這也意味著我們專案的依賴性更高。 更不用說這些庫仍處於開發階段,並定期引入重大變化。 因此,您需要在專案中謹慎維護這些依賴關係。 這為JavaScript開發增加了另一層複雜性。 您典型的React應用程式至少具有以下依賴項:
- 靜態型別 - Flow / TypeScript
- 不變性 - immutableJS
- 路由 - ReactRouter
- 格式 - Prettier
- linting - ESLint
- 輔助功能 - Ramda / Lodash
現在讓我們用 ReasonReact 來替代 JavaScript React。 我們還需要所有這些依賴嗎?
- 靜態型別 - 內建
- 不變性 - 內建
- 路由 - 內建
- 格式 - 內建
- linting - 內建
- 輔助功能 - 內建
您可以在我的其他帖子中瞭解有關這些內建功能的更多資訊。
在ReasonReact應用程式中,您不需要這些和許多其他依賴項,因為許多使您的開發更容易的關鍵功能已包含在語言本身中。 因此,維護您的軟體包將變得更加容易,並且您不會隨著時間的推移而增加複雜性。 這要歸功於已有20多年曆史的OCaml。 它是一種成熟的語言,其所有核心原則都已到位且穩定。
Wrap-up
起初,Reason的創造者有兩種選擇。 採用JavaScript並以某種方式使其更好。 通過這樣做,他們還需要處理其歷史負擔。 但是,他們採取了不同的方式。 他們將OCaml作為一種成熟的語言,具有出色的效能並對其進行了修改,使其類似於JavaScript。 React也基於OCaml的原理。 這就是為什麼當你在Reason中使用它時,你將獲得更好的開發者體驗。 React in Reason代表了構建React元件的更安全的方式,因為強型別系統已經得到了迴應,您不需要處理大多數JavaScript(遺留)問題。
What’s next?
如果您來自JavaScript世界,由於其與JavaScript的語法相似性,您可以更輕鬆地開始使用Reason。
如果你一直在React中程式設計,那麼你會更容易,因為你可以使用你所有的React知識,因為ReasonReact具有與React相同的心理模型和非常相似的工作流程。
這意味著您無需從頭開始。
隨著您的發展,您將學習理性。
在專案中開始使用Reason的最佳方法是逐步進行。
我已經提到你可以使用Reason程式碼並在JavaScript中使用它,反之亦然。
您可以使用ReasonReact執行相同的操作。 您可以使用ReasonReact元件並在React JavaScript應用程式中使用它,反之亦然。
這種增量方法已被Facebook開發人員選擇,他們在開發Facebook Messenger應用程式時廣泛使用Reason。
如果你想使用React in Reason構建一個應用程式並以實用的方式學習Reason的基礎知識,請檢視我的其他文章,我們將在一起構建一個Tic Tac Toe遊戲。
如果您有任何問題,批評,觀察或改進提示,請隨時在下面寫評論或通過Twitter或我的部落格與我聯絡。