標籤:targe this 第一個 複用 class www. 協助 預覽 strong
正如你能從標題猜到的,這篇文章的目標是給那些有很少編程經驗的讀者的。比如,像我這樣的人:因為迄今為止,我才探索了編程世界6個月。所以,這將是一篇新手村教程! 你只需要擁有對 HTML 和 CSS 的理解,以及基本的 JavaScript(JS)知識就能看懂本文。
注意:在接下來的例子中,我們將會利用 ES6 提供的新能力,來簡化寫 JS 代碼的過程。然而,你也能完全使用 ES5 來寫 React。
預計閱讀時間9分鐘
什麼是 React ?
React 是一個 JS 庫,由 Facebook 和 Instagram 建立(https://facebook.github.io/react/)。它通過將應用分為一些動態、可複用的 組件,來使我們可以建立單頁應用(Single Page Applications (SPA))。
一個 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() 總 會返回一個 div,而在其中開發人員可以自由引入他們認為合適的任意多的標籤和元素。
例子:海盜的滅絕
如果我們選擇使用 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 新手教程