學習 React.js : 概念和起步
Learning React.js: Getting Started and Concepts By Ken Wheeler (@ken_wheeler) #簡介 今天我們開始一個新系列的學習,學習 React,我們將集中在怎麼熟練並且有效的使用臉書的 React 庫上。在我們開始實際寫程序之前,還有更重要的一步,我們先講解一些基本概念,好了,我們開始吧。 ##什麼是 React? React 是臉書開發的一個 UI 庫,可以用來方便創建具有交互性,狀態性 & 重用性的 UI 組件。它已經被哂迷诹四槙纳a環境上了,並且 Instagram.com 也完全是用 React 來寫的。 它的一個獨一無二的買點是,它不僅能用在客戶端,還能在服務端渲染,並且可以配合著用。 它還有一個概念叫做虛擬DOM,它會基於狀態更新選擇性的進行渲染子節點。這使得你的組件通過最少的DOM操作保持更新。 ##虛擬DOM是怎樣工作的? 想象一下,你有一個人類模型。它有一個人應該有的各種屬性,並且反映了這個人當前的狀態。React 差不多就是這樣對待 DOM 的。 現在再想一下,如果你讓這個對象發生一些改變,比如說加個小鬍子,然後再加點肌肉,再加雙 Steve Buscemi 那樣的眼睛。在 React 世界,當你做了這些更新之後,有兩件事情會發生。首先, React 執行"髒值檢查",確定發生了什麼改變。然後第二步是調和,把檢測到的更新結果反映到 DOM 上。 React 的方式,不會真的去再生一個小孩出來,重新把他們養大,而只是做個臉和手臂的整形。也就是說,如果你在輸入框裏面的文字發生改變,除非輸入框的父節點發生渲染,否則文字將會保持原狀。 由於 React 用的是假的 DOM 而不是真的那個,那麽這就讓有了一種新的可能。我們可以在服務端來渲染這個假的 DOM,然後,duang~服務端的 React View。 #開始 想要開始用 React 很簡單,只要去下載他們提供的 starter kit 就好: React Starter Kit 你也可以叉他們提供的 JSFiddle: React JSFiddle ##頁面設置 那麽我們來設置頁面,你需要導入 <!-- lang: js --> <!DOCTYPE html> <html> <head> <script src="build/react.js"></script> <script src="build/JSXTransformer.js"></script> </head> <body> <div id="mount-point"></div> <script type="text/jsx"> // React Code Goes Here </script> </body> </html> 在 React 裏面,組件必須加載到一個元素上,所以在例子裏面,我們可以用 div 當然這只是一個最簡單的起點,黨你實際上要寫點什麼的時候,最好用 Browerify 或者 webpack 這樣的工具來把你的組件拆分到不同的文件中。 #基礎 React 的基本單元模塊叫做組件(component),讓我們來寫一個: <!-- lang: js --> <script type="text/jsx"> /** @jsx React.DOM */ React.renderComponent( <h1>Hello,world!</h1>,document.getElementById('myDiv') ); </script> 如果你沒看之前的代碼,那你肯定一頭霧水不知道這個 javascript/HTML 到底做了什麼。 ##JSX 這就是所謂的 JSX,它是一種 Javascript XML 語法轉換,可以讓你在你的 Javascript 裏面寫 類HTML。我之所以說 類HTML 是有多重含義。你僅僅是基於一個關聯對象來寫 XML 。 對於正常的 html 標籤,在 JSX 中, 如果你不用 JSX,那麽這裏是不用它的一個版本: <!-- lang: js --> /** @jsx React.DOM */ React.renderComponent( React.DOM.h1(null,'Hello,world!'),document.getElementById('myDiv') ); 如果你願意,你可以看這裏,來瞭解更多支持的元素。 在你的第一個代碼片段裏面,你有沒有注意到在頂行的 ##組件 黨使用上面的 <!-- lang: js --> var MyComponent = React.createClass({ render: function(){ return ( <h1>Hello,world!</h1> ); } }); 創建一個類之後,我們可以在 document 中像這樣渲染它: <!-- lang: js --> React.renderComponent( <MyComponent/>,document.getElementById('myDiv') ); 屌不屌,嗯哼? ##Props 當我們使用我們定義的組件的時候,我們可以添加屬性,叫做 props,這些屬性在我們的組件仲可以通過 <!-- lang: js --> var MyComponent = React.createClass({ render: function(){ return ( <h1>Hello,{this.props.name}!</h1> ); } }); React.renderComponent(<MyComponent name="Handsome" />,document.getElementById('myDiv')); ##Specs,生命週期 & 狀態
###生命週期方法
###Specs
###State 每個組件都有一個 <!-- lang: js --> var MyComponent = React.createClass({ getInitialState: function(){ return { count: 5 } },render: function(){ return ( <h1>{this.state.count}</h1> ) } }); ##事件 React 還有一個內建跨瀏覽器事件系統。這些事件可以作為組件的屬性來追加也可以觸發方法。讓我們來通過事件來創建一個計數器: <!-- lang: html --> <div id="mount-point"></div> <!-- lang: js --> /** @jsx React.DOM */ var Counter = React.createClass({ incrementCount: function(){ this.setState({ count: this.state.count + 1 }); },getInitialState: function(){ return { count: 0 } },render: function(){ return ( <div class="my-component"> <h1>Count: {this.state.count}</h1> <button type="button" onClick={this.incrementCount}>Increment</button> </div> ); } }); React.renderComponent(<Counter/>,document.getElementById('mount-point')); <!-- lang: css --> body { background: #bdc3c7; padding: 40px; } .counter { width: 300px; margin: auto; background: #9b59b6; color: white; padding: 20px; text-align: center; h1 { margin: 0; padding: 20px; font-size: 36px; } button { background: #f1c40f; border: 0; box-shadow: 0px 5px 0px darken(#f1c40f,20%); padding: 20px; width: 100%; outline: none; border-radius: 3px; color: darken(#8e44ad,10%); font-weight: bold; } } ##單向數據流 在 React 中,英勇的數據通過 如果需要,你的狀態可以通過使用 下面用一個例子來解釋這些概念: <!-- lang: js --> /** @jsx React.DOM */ var FilteredList = React.createClass({ filterList: function(event){ var updatedList = this.state.initialItems; updatedList = updatedList.filter(function(item){ return item.toLowerCase().search( event.target.value.toLowerCase()) !== -1; }); this.setState({items: updatedList}); },getInitialState: function(){ return { initialItems: [ "Apples","Broccoli","Chicken","Duck","Eggs","Fish","Granola","Hash Browns" ],items: [] } },componentWillMount: function(){ this.setState({items: this.state.initialItems}) },render: function(){ return ( <div className="filter-list"> <input type="text" placeholder="Search" onChange={this.filterList}/> <List items={this.state.items}/> </div> ); } }); var List = React.createClass({ render: function(){ return ( <ul> { this.props.items.map(function(item) { return <li key={item}>{item}</li> }) } </ul> ) } }); React.renderComponent(<FilteredList/>,document.getElementById('mount-point')); <!-- lang: html --> <div id="mount-point"></div> <!-- lang: css --> * { box-sizing: border-box; } body { padding: 20px; background: #2c3e50; } .filter-list { margin: auto; width: 300px; background: #3498db; border-radius: 5px; border: 1px solid darken(#3498db,20%); input { width: 100%; display: block; padding: 10px; border-radius: 5px 5px 0px 0px; border: 0; font-size: 24px; &:focus { outline: none; } } ul { margin: 0; padding: 0; li { list-style-type: none; margin: 0; color: white; padding: 10px 20px; border-top: 1px solid darken(#3498db,20%); &:hover { background: #2980b9; } } } } #總結 我們已經介紹了一些 React 的基礎知識了,花點時間去看看 React API 和學一下 JSX。 在學習 React 的下一張,我們將結合 Express 來創建一個在服務端渲染的應用,就像在客戶端一樣,然後使用 socket.io 來保持兩邊同步。 敬請期待! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |