React.js 新手教程
正如你能從標題猜到的,這篇文章的目標是給那些有很少編程經驗的讀者的。比如,像我這樣的人:因為迄今為止,我才探索了編程世界6個月。所以,這將是一篇新手村教程! 你只需要擁有對 HTML 和 CSS 的理解,以及基本的 JavaScript(JS)知識就能看懂本文。
註意:在接下來的例子中,我們將會利用 ES6 提供的新能力,來簡化寫 JS 代碼的過程。然而,你也能完全使用 ES5 來寫 React。
預計閱讀時間9分鐘
什麽是 React ?
React 是一個 JS 庫,由 Facebook 和 Instagram 創建(https://facebook.github.io/react/)。它通過將應用分為一些動態的、可復用的 組件
一個 React 組件是一個繼承了由 React 提供的 Component 的 JS 類。一個組件代表並定義了一塊 HTML 代碼,以及任何與這塊代碼相關的行為,比如點擊事件。組件就像是樂高積木,可以用來組建成所需的復雜應用。完全由 JS 代碼構成的組件,可以被隔離和復用。基本方法是 render(),它簡單地返回一片HTML代碼。
這種用來定義 React 組件的語法被稱為 JSX。該語法由 React 的創建者們所開發,被用來簡化 JS-HTML 代碼的組件內交互。使用該語法寫的代碼在變成實際 JS 代碼前必須被編譯。
創建一個組件(component)
為了創建我們的組件並將它渲染為一頁 HTML,我們首先在我們的 HTML 文件裏需要定義一個有唯一 id 的 div。接著,我們將要在 JSX 文件裏寫代碼,以連接 React 組件到使用其 id 的 div,如下面的例子所示。這樣做將會指導瀏覽器在相關 DOM 標簽所在的頁面渲染組件。
See the Pen Start by Makhenzi (@makhenzi) on CodePen.
JSX 內的 HTML 標簽屬性和普通 HTML 內的是幾乎一樣的;唯一不同的是“class”,在 JSX 裏面變成了“className”。類 HTML 語法使用圓括號閉合,而包含 JS 的塊則使用尖括號閉合。正如你將看到的。render() 總
例子:海盜的滅絕
如果我們選擇使用 React 來創建這張圖,我們可以對屏幕上各個日期進行可視化,並在那些日期被點擊的時候,才顯示對應的溫度和海盜數量。
為此我們需要2個組件:第一個用來渲染日期,並將每個日期鏈接到給定的海盜數量和溫度;第二個則需要用來接收日期上的點擊事件對應的信息,如海盜的數量和當時的溫度,接著基於這些數據渲染選擇的元素。
前者相當於是“父親”的角色,並包含多個後面的“子”組件的鏈接,而後者則緊密依賴於它們的“父親”。
React 結構,被稱為虛擬 DOM,可以使我們在組件的內容發生改變的時候,不需要刷新整個頁面,而可以只更新對應組件。為此,組件需要一個內部方法,來保存變量 data 和 賦值給該元素的會被改變的 HTML 屬性。這些屬性會自行鏈接到那些我們在組件內定義的,會負責響應變化的方法。
狀態(State)和屬性(props)
在我們的例子裏,那個獨立的變量 data 是由日期組成的。這些會根據點擊事件所集合的 DOM 內連鎖反應進而根據對應海盜、溫度信息而進行改變。所以我們將會根據每個 “DATA” 對象內的對應日期去保存信息。我們還將利用 React 在父組件內的 this.state={}
屬性來以鍵值對拷貝形式保存變量數據的。
以這種形式組織程序使得我們可以利用 React 提供的方法,來以“狀態(state)”的形式和數據交互,並對其進行任意更改。
考慮到我們想要使用 DATA 對象的 key 來渲染 HTML 內的日期,最好可以找到一種方法來在 key 上使用 JS 的 map()
方法(Array.prototype.map()),以便能直接顯示返回到 render()
的 HTML。事實上確實有方法可以做到!我們只需要把 JS 代碼包裹在雙花括號裏,並放置在想要代碼輸出顯示的管理該組件的 DOM 塊內,然後就好了。
在這個特殊例子中,我們將在組件內的方法裏定義 map()
回調,其將在同一組件的render()
內返回一片 HTML 代碼。
See the Pen State1 by Makhenzi (@makhenzi) on CodePen.
為了分配點擊事件到每個日期,我們將會分配 onClick
屬性給它們。
在該屬性中,我們會調用組件的方法,該方法則會定義我們希望在 onClick 事件後觸發的狀態修改和其他變更。
在我們的例子裏,我們定義該函數為 handleClick()
。在 handleClick() 中,我們會調用 React 方法 setState()
,其允許我們在在每個點擊事件中去更改狀態數據。我們只需要插入一個包含我們想要修改的狀態 key 的對象,並在後者括號內分配給它們新的相關聯值。
總的來說,每次一個日期被點擊,被選中的div的onClick屬性會調用 HandClick()
方法,該方法會調用 setState() 方法來修改組件的狀態。
每次狀態改變,一旦發生 React 就會自動檢查組件的 render()
函數的返回,以尋找基於新狀態需要更新的內容。一旦有那樣的數據, React 就會自動觸發一次新的 render()
來更新那些有變更的 HTML 片段。
(我很抱歉,在接著的例子裏,我插入了三行利用了 Classnames 的代碼,一個用來基於狀態變更來做 CSS 管理的小工具,我這麽做只是為了給預覽一點顏色。我還會使用它在最終的例子裏給預覽填充一些海盜變量。你可以找到 GitHub 上 Classnames 倉庫的鏈接,還有一個簡要使用向導)
See the Pen State2 by Makhenzi (@makhenzi) on CodePen.
如此,我們的父組件狀態已經被設定好根據選中數據去創建子組件(其將會描述海盜數量和對應溫度)。
我們將會在 JSX 文件中創建子組件的實例,正如我們之前對父組件所做的。為了鏈接子組件到其父親上,我們只需要在後者的 render()
函數使用同一種語法和一個 HTML 標簽去定義關系。如果我們稱它為 “Child” ,它將會在我們插入 <Child />
處所在的 HTML 塊內出現。
我們的子組件還必須根據現在選中數據所關聯的海盜和溫度,傳遞數據到其父親。為此,我們將利用賦給 Child 標簽的屬性,其名字可以隨便取,其信息只對父組件可見。
如此一來,子組件將可以通過顯式訪問歸屬於其父組件的數據,即利用這些 “attribute-bridges”,或者 屬性(props),來獲取到它自己內部信息的訪問權。
所以,每次父組件的狀態發生改變,其子組件的屬性內容就會自動進行更新。但是,正如子組件的render()
方法會顯示屬性內容,它也會基於單向的數據線性流,根據任何收到的新信息去進行更新。
搞定了!組件們會互相交互,並根據我們的點擊在 DOM 裏渲染不同數據,而不需要單頁去進行刷新。以這個為基礎,交互的復雜性和組件的數量可以按需增加,使我們能創建復雜高效的應用。
如果你被這個庫的潛力啟發了,不妨看看 react.js example 網站,在那裏你會找到很多有趣的點子來幫助你開始。(:
React.js 新手教程