Pages

搜尋此網誌

2014年10月18日 星期六

JSDC 推坑之 react: component for UI

JSDC 推坑之 react: component for UI

有一定的開發經驗後,相信有些地雷踩過你一定不想再踩一次,技術的演進一樣是為了解決一些問題,某種程度上希望避免一些不必要的錯誤。

這週末參加了 JSDC 舉辦的研討會,剛好聽講者 Jeremy Lu 推坑 React:一個易學效率好令人驚豔的前端框架,趁還新鮮找個小玩具來用 react 實作看看,該講者的簡報在這

之前因為專案需要開發了一個 facebook 中關於廣告操作的工具 power edit,目前專案使用上前端使用的是 angular:ng-dateGridTool

這次為了學習 react 花了兩天時間把該套件重新改寫,產出了另外一個版本:react-dateGridTool

enter image description here

運行方式可以參考專案中的 readme。

同樣的功能需求,用來測試新的框架正好可以驗證比較,一些關於 react 的基本知識這邊就不談,主要說明的是在使用 react 開發上的一些 Tips。

在看這篇文章前,需要知道的是這邊不說基礎的 react 知識,請先有基本的 react 使用經驗。

JSX 界的 coffeeScript: CJSX

首先,在之前的開發習慣中,慣用 coffee script 所以在一開始嘗試使用 react 特有的 JSX 若直接使用 coffee script 的話,無法正常編譯完成,因為在 js 檔案中使用類似 HTML 的 tag 會造成 Syntex Error,如:

Team = React.createClass 
    render: -> 
      <div className="team"> 
        <div>{@props.team.name}</div>
        <div>{@props.team.city}</div>
      </div>

大概搜尋了一下,還好 jsx 也有類似 coffee 的對應副檔名,叫做 cjsx,參考 Using React’s JSX with CoffeeScript and Sublime Text,對 cjsx 的使用方法有一些介紹。

對於上述語法的使用,可以參考 react 的官方網站說明:JSX in Depth

JSX 界中的類 jade 做法

除了 coffeeScript 的使用以外,原本在寫 HTML 時也習慣使用 jade 的使用,用 jade 的好處,就是在宣告 html tag 時可以避免忘記 close,如 </ div>,大概研究一下,在 jsx 中似乎也沒有可以自動辨識 jade 語法的方式,若用上述的範例為例,理想的做法如下:

Team = React.createClass 
    render: -> 
      div(className="team") 
        div {@props.team.name}
        div {@props.team.city}

不過上面的範例是錯的,cjsx 會不認得,不過一旦曾經方便過,再回去使用一般的 html 語法還是卡卡的,幸好,jsx 的另外一個撰寫方式搭配 coffee 的話算是還可以接受,如下:

div = React.DOM.div
Team = React.createClass 
    render: -> 
      div {className: "team"}, [
        div null, @props.team.name
        div null, @props.team.city
      ]

雖無中的,但相去不遠;這樣的寫法還有好處,如果我需要用 repeat 的方式產生 html element,可以把屬性用 Object 先建好,如:

div = React.DOM.div
test = () ->
  console.log "test"

attr = {
  className: "team"
  onClick: test
}

elements = [0..5].map (index) ->
    return div attr

如此一來就快速建好所有的相同屬性的 div,可能有人覺得有差麻?沒辦法,就是懶~

基本的開發所需習慣的 syntax 準備好後,在開發 react 的時後,就可以思緒順暢的有節奏的進行!

在開發中有些技巧跟大家分享,第一件事是必須先理解 Passing BY value OR BY Reference 的不同,參考 JavaScript中參數的傳值與傳址心得 這篇寫得蠻清楚的,有了這樣的認知後在物件相關值的變更上,就不會無所適從,假設你希望 parent component 的屬性傳到 children component,並且因為 children component 的事件觸動因而改變 Object 時也可以被 parent component 索取用,就使用 object reference 的方式,如:

div = React.DOM.div
test = () ->
  console.log "test"

attr = {
  className: "team"
  onClick: test
}

elements = [0..5].map (index) ->
    return div {attr: attr}

return div attr 改為 return div {attr: attr};如此在 child component 中的變動在 parent 就可以共享同一個 object。

其實某一個方面來說,我們可以把 react 中的 component 視為 javascript 中的 function,只不過他是有 view 的 function,若是這樣想是不是就沒這麼難懂?我個人是這麼想的。不過是改用 html 形式的 function ,這也是我的 title 的命名原因:react: javascript function for UI

所以,有這樣的基本認知後,在進行 component 的相關互動時,該在哪個層級操作 UI 之事件就會比較有所依據,官方文件中,關於各個 component 間的互動與 referance,建議可以依序下述官方文件看起:

透過上述兩篇文件的介紹,基本上在存取 compnent 進行操作上應該就沒問題了,配合存取方式的操作可以更進一步閱讀下述文件

有了上述技巧,可以讓你很方便封裝 component,並且與其他 component 互動,掌握這些知識之後,關於 react 的操作應該會比較輕鬆一點囉!

結論

因為之前有使用 angular 的經驗,一開始使用 react 的時候有點適應不良,實際做過一個小工具後,總算比較了解其特性,也能體會 JSDC 中講者所說的容易學習。

框架雖然方便,暸解 javascript 的基本知識才能夠隨心所欲,舉凡 map,bind 或是 reference 都是很容易搞混或錯用,造成結果不如預期,咦!要注意。

延伸閱讀

react 也可以透過 Browserify 在 server-side render,參考下列連結:

張貼留言