? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 關于React的一些你應該知道的東西
親愛的讀者們!
這本書假設你已經知道什么是React以及其能解決你什么樣的問題,你或許已經用它寫過中小型的應用,如果你想要提高自己的技能,本書能為你解答你未能解決的問題。
你應該知道React是由Facebook和幾百位javaScript的社區貢獻者維護和開發的,由于采用了虛擬DOM的技術使得它運行起來非???,目前React是github上創建用戶UI最流行的庫之一。
React 使用JSX語法,用一種javaScript標記型語法,這種語法需要你以一種組件化的思維思考并且有很多很酷的特性,比如能夠使我們寫通用的應用(一套代碼,能同時運行到服務端和客戶端環境)服務端的渲染。
本教程需要你知道如何在node的環境下使用終端命令安裝和運行NPM包。
所有的式例采用ES6(es2015),你應該能夠看懂和理解。
在第一個章節里。將會介紹一些基本的概念,這對于一個新手弄明白Reat非常有意義,同時對一個熟練React的人高效地使用React也是非常重要。
-命令式編程和聲明式編程之間的區別
-什么是React組建及它的實例,以及React 如何使用元素控制UI界面
-React如何改變編譯web應用的方式,執行關注點分離新的概念,和這種不受歡迎的設計選擇背后的原因
-為什么開發者感到JavaScript不給力以及使用React的生態系統如何避免一些常見的錯誤
聲明式編程
閱讀React文檔或者關于React的博客,你一定看到聲明式這個單詞,
實際上,React如此強大的一個原因是它實行了聲明式編程范式,因此掌握React,理解聲明式編程和與命令式編程的不同很重要,他們的不同之處最簡單的方法是認為:命令式編程是描述如何去做事情,聲明式編程是描述你想要的是什么
舉個簡單的例子,假設我們想讓一個數組里的字符轉小寫。
toLowerCase(['FOO', 'BAR']) => ['foo', 'bar']
我們用命令式編程風格實現,像下面這樣:
const toLowerCase = input => {??
? ? const ouput = []
? ?for (let i = 0; i < input.length; i++) {? ??
? ? ? ouput.push(input[i].toLowerCase())??
? }??
? return ouput;
}?
首先,創建一個空的數組,然后,通過遍歷每個數組的元素轉化成小寫,最后,返回結果。
用聲明式編程風格實現,像下面這樣:
const toLowerCase = input => input.map(value => value.toLowerCase())
map利用當前的數組創建了一個新數組,新數組里的每個元素都是經過了傳入map的函數(value => value.toLowerCase()))的處理
這兩種編程風格的不同:前面的例子,不優雅并且很難理解,后一種,簡單容易閱讀,在大型的項目里面,維護起來后者更方便,
另外一個值得一提的是聲明式的既不需要聲明變量也不需要在執行后保持最新的值,不會改變外部狀態。
最后再舉個例子看看React中的聲明式編程式怎樣的,我們會以最web開發中常見的需求:“顯示地圖用一個標記點” 展開來講,像下面這樣
const map = new google.maps.Map(document.getElementById('map'), {? zoom: 4,? center: myLatLng, })
const marker = new google.maps.Marker({? position: myLatLng,? title: 'Hello World!', })
marker.setMap(map)
明顯的命令式,創建map、marker和附加到map上,
React組建是如何顯示map在頁面上的呢?
<Gmaps zoom={4} center={myLatLng}>
? <Marker position={myLatLng} title="Hello World!" />
</Gmaps>
使用聲明式編程,開發者只需要描述想要的是什么,不需要羅列出具體的步驟,實際情況是它使用方便,代碼更優雅,明顯減少bug,更易維護。
React 元素
本書假定讀者熟悉組建及其實例,如果你想高效地使用React還有一種對象讀者也應該知道:Element,無論你是調用creatClass,繼承Component 或者簡單地聲明無狀態的函數,都會創建組建,react在運行時管理組建的所有實例,在某個時間點上可能有相同組建的一個以上的實例在內存中。
如前所述,React尊從聲明式編程,不需要告訴它怎樣和DOM交互,只需聲明你需要在頁面上顯示什么,其他的React已經幫你做好了,
你可能有這樣的體驗,許多其他的UI庫用的是相反的方式,他們不處理保持界面更新,而是手動處理創建和銷毀DOM元素,
為了控制UI流,React使用特殊的類型對象,叫做elements, 它描述顯示在屏幕上的東西,這種不可變的對象比起組建和組建的實例來講更簡單并且只是顯示界面。
下面是一個elements的例子,
{??
? ? ?type: Title, ?
? ? ?props: {? ? color: 'red',? ? children: 'Hello, Title!' ?}
}
elements 有一個type和其他的屬性,type是最重要的屬性,它告訴elements,如何處理自身,實際上,如果type是一個string,elements代表一個DOM 節點,如果是一個函數則代表一個組建
有一個children是可選的,代表這個elements的子elements,
elements和組建能過被相互嵌套,
{
? type: Title,?
? props: {? ??
? ? ?color: 'red',? ??
? ? ?children: {? ? ??
? ? ? ? ?type: 'h1',? ? ?
? ? ? ? ?props: {? ? ? ??
? ? ? ? ? ? ? ? ? children: 'Hello, H1!'? ? ?
? ? ? ? ? ? ? ? ?}? ??
? ? ? ? ?}?
? }?
}
當type為函數時,react遞歸執行,直到返回DOM node,這一處理過程稱為reconciliation,被使用在React DOM和 React native中創建用戶界面根據各自的平臺。
清掉一切
對于第一次使用React的開發者來說并不是件容易的事,它需要開放的思維
其實,React嘗試改變我們構建用戶界面的方式,用一種打破被認為是最佳實踐的方式。
在過去的二十年里,我們已經知道了關注點分離是很重要的,過去是從將邏輯從模版中分離這個角度理解它的,具體的實現是將Javascipt和html代碼寫到不同的文件,(不要寫"行內樣式"(inline style)和"行內腳本"(inline script))
為了實踐上面所說的分離關注,多種模版解決方案被創建出來,慢慢地,你會發現,許多時候這種分離只是一種錯覺,實際情況是Javascipt和html代碼緊密耦合在一起,
讓我們來看一個模版的例子:
{{#items}}??
? ? ? {{#first}}
? ? ? ? ?<li><strong>{{name}}</strong></li>
? ? ?{{/first}}?
? ? ?{{#link}}
? ? ? ? ? <li><a href="{{url}}">{{name}}</a></li>
? ? ? {{/link}}
?{{/items}}
這段代碼是從Mustache(是一個 logic-less (輕邏輯)模板解析引擎)的官網上摘抄下來的,第一行告訴Mustache循環集合items,在循環的內部,如果first和link存在則渲染html標簽,變量封裝在雙大花括號里,如果你的應用只是顯示一些變量,模版庫是一種好的選擇,但是當面臨復雜的數據結構則并適合,
其實模版系統和它的(DSL)領域特定語言提供子集的特性,這些模版只是提供特定的功能而不是達到同樣高度的完整性,正如上面的例子所示,模版展示的信息高度依賴從邏輯層獲取的數據模型,
另外,通過模版更新用戶界面,Javascipt與DOM 元素的交互渲染即使分離的文件已經加載完成,
同樣的問題也出現在樣式,樣式被定義在不同的文件里,被模版引用,CSS選擇器遵從標記語言的結構,因此只要改變一個就會改變其他的,樣式是一種耦合定義的。
這也是為什么典型的關注點分離最后成為技術的分離,這當然不是一件壞事,但是它沒有解決任何實際的問題,而react則把模版放一邊(專門用來處理邏輯),這樣做的原因是react提倡構建應用使用小的積木(叫做組建)組合起來,這個框架不會告訴你如何關注點分離是因為只有開發者自己知道和決定應用的邊界,
基于組建的開發大大地改變了編寫web應用的方式,關注點分離的概念漸漸地被現代框架所取代,這種范式被React實現并不是一個新的事物,也不是被它的創建者發明出來的,只是React使它成為主流,更重要的是,使它容易理解和受歡迎,下面是React 組建的渲染例子
render() {
? ? <button style={{ color: 'red' }} onClick={this.handleClick}>
? ? </button>
? return (Click me!)
我們會感覺這種寫法看起來有些奇怪,不要著急,用慣了就能發現它的便利,
使用js寫的邏輯和模版不但有助于關注點分離,而且還對復雜的用戶界面強大和表現力,