系列學習react 翻譯地址 https://scotch.io/tutorials/learning-react-getting-started-and-concepts
我是初學者,英語也不是很好,不過一直強迫自己看英文文檔。
這是理解翻譯,翻譯的不好,請見諒!()中的是我翻譯過程中理解,參考下,有什么說的不對的歡迎指點下!
第一節:如何開始react和了解react的概念
1.React是什么
react是Facebook 開發出來用於促進UI交互,創建帶有狀態的,可復用的UI組建的UI庫!Feacebook的產品廣泛運用這技術,Instagram.com(一款圖片分享應用)基於react開發出來的。(這里的理解難點在於 帶有狀態的,可復用的UI組件。也就是一個UI組件,它帶有狀態屬性,並且可重復使用!)
react的最大的賣點就是,react不僅可以在瀏覽器端使用,還可以在服務端使用,還可以兩端一起使用!
react的底層的概念:react運用的是Virtual DOM(虛擬DOM),然后根據UI組件的狀態變化,有選擇的渲染DOM的節點樹!它盡可能的操作最少的DOM來更新UI組件。
2.虛擬DOM是如何工作的?
想象下,你建立一個關於人的對象。這對象擁有人的每一個屬性,然后這對象就像鏡子一樣,映射出一些人中每一個人的所有屬性。這就是React與DOM的主要關系。
(我是這么理解的,React的虛擬DOM盡可能的擁有DOM的一切屬性,然后在應用中使用虛擬DOM映射出當前應用需要的所有DOM節點!)
現在,如果我們給這個對象,添加一個胡子、一些肱二頭肌、Steve Buscemi 的眼睛(給人對象的某個實例添加這些)。在react中,當我們需要這些變化產生,(react)會發生兩件事。第一件事,就是react會運行"差異"算法,也就是前跟后發生了哪些變化。第二件事,就是把這種"差異"算法的出的結果更新到DOM上(應該是虛擬DOM)
React的這種運行模式不同於依照變化前的人,然后開始重新把這些變化后的人塑造出來(我是這里理解的,原本的DOM要變化一個節點,需要新建一個節點再把變化加上去,然后再去替換之前的節點。而react的方式,就是在它自己的虛擬DOM上直接把需要變化的地方,變化下OK了)。它只需要換下臉和手臂。這就意味着,如果你想要在input輸入框中把一些文本渲染出來,只要輸入框的父節點沒有安排改變,它將會保持原狀!(只修改要變化的,不要變化的保持原狀!)
3.開始React的准備
第一步,下載開發包。下載地址:http://facebook.github.io/react/downloads/react-0.11.2.zip
你也可以用bower安裝新版的react。
bower install react
第二步,在頁面中引入react庫。
在頁面中引入react庫,分別引入react.js和JSXTransformer.js這兩個文件。然后在自己的type為text/jsx的srcipt標簽中寫應用組件。
<!DOCTYPE html> <html> <head> <title></title> <script src="bower_components/react/JSXTransformer.js"></script> <script src="bower_components/react/react.js"></script> </head> <body> <div id="mount-point"></div> <script type="text/jsx"> //這里的type是text/jsx //這里你的代碼 </script> </body> </html>
在react中,組件都是綁定到一個元素中,上面的例子就是用id 為mount-point的div作為組件的容器。
這種事開始react的最簡單的方法。但在實際應用中,使用Browserify或者webpack把組件代碼放到單獨文件中的方法更好。
4.React的基礎
現在我開始一個簡單的展示:
<script type="text/jsx"> React.render( <h1>Hellow, World!</h1>, document.getElementById('mount-point') ) </script>
用瀏覽器打開html頁面,效果就是:
5.JSX
這種寫法叫JSX。這是一種javascript XML語法的轉換(javascript 中的XML語法)。這可以讓你在javascript中編寫html標簽。其實你編寫的是基於對象展現的XML。
對於常規的html標簽,在JSX中class屬性是className,for屬性是htmlFor。應為class、for等都是javascript的保留字。更多的不同你可以看這里 (http://facebook.github.io/react/docs/jsx-gotchas.html)
如果你不用JSX語法編寫,用存粹的javascript的語法你可以這么寫。
<script type="text/javascript"> React.render( React.DOM.h1(null, 'Hello, World!'), document.getElementById('mount-point') ) </script>
在網頁中也能顯示出Hello, World!
6.組件
當時調用render的方法時,它的第一個參數就是就要選人的組件。第二個參數就是你想定綁定的DOM節點。
我們可以使用createClass方法創建一個自定義的組件。它接受一個對象格式的參數。例子如下:
var MyComponent = React.createClass({ render: function(){ return ( <h1>Hello, world!</h1> ); } });
創建了一個組件之后,可以把MyComponent渲染到我們的DOM中:
React.render( <MyComponent/>, document.getElementById('mount-point') )
7.Props
當我們使用定義的組件時,我們可以給它添加props屬性。這屬性非常有作用,在我們的組件中作為this.props。當我們想要渲染動態數據就使用它。
列子如下:
var MyComponent = React.createClass({ render: function () { return ( <h1>Hello, {this.props.name}!</h1> ); } }); React.render( <MyComponent name="Ailen"/>, document.getElementById('mount-point') )
顯示結果就是:
8.規范,生命周期和狀態
創建一個組件, render 方法是唯一需要的規范。但我們的組件想要完成其他一些事情時,這里有幾個生命周期方法和規范供組件有效的完成這些事情。
生命周期方法:
1.componentWillMount(組件將要安裝綁定):在客戶端和服務端 組件被渲染之前,componentWillMount執行一次。
2.componentDidMount (綁定安裝過的組件): 組件渲染完成后僅在客戶端compoentDidMount調用一次。
3.shouldComponentUpdate(應該更新的組件):返回值決定組件是否要更新。
4.componentWillUnmount(將要取消安裝綁定的組件):優先調用要取消安裝綁定的組件。
(這里我也是一知半解)
Specs(規格,規范)
1.getInitialState: 為狀態返回一個初始化值。
2.getDefaultProps:如果為提供props,設置回退的props值。
3.mixins: 通過一個關於對象的數組來擴展組件的功能性。
關於更多的specs 和 lifecycle方法可以點擊鏈接:http://facebook.github.io/react/docs/component-specs.html
State(狀態)
每個組件都有一個state對象和一個props對象。state使用setState方法,調用setState來觸發視圖更新和React的交互性。如果我們想在交互發生之前設置一個默認的狀態,可以使用getInitialState方法。下面舉例演示組件的狀態:
var MyComponent = React.createClass({ getInitialState: function () { return { count: 5 } }, render: function () { return ( <h1>{this.state.count}</h1> ) } }); React.render(<MyComponent/>, document.getElementById('mount-point'));
9.Event(事件)
react也提供一套能夠兼容各瀏覽器的事件系統。這些事件作為屬性添加組件上可以觸發方法。
下面我們通過事件來實現count自增。
var MyComponent = React.createClass({ incrementCount: function () { //修改state 通過setState方法 this.setState({ count: this.state.count + 1 }) }, //getInitialState 初始化state的值 getInitialState: function () { return { count: 5 } }, render: function () { return (
//友情提醒、react的組件必須用一個一個容器包裹下。也就是這里的div。如果只有一個標簽例如:<h1>hello, world!</h1>就不需要div包裹了。 <div> <h1>{this.state.count}</h1> <button type="button" onClick={this.incrementCount} >Increment</button> </div> ) } }); React.render(<MyComponent/>, document.getElementById('mount-point'));
感覺很酷哦!
10.Unidirectional Data Flow(單向數據流)
react中,應用的數據傳遞是單向的通過state和props對象,不同於angular的雙向數據綁定。單向數據流的意思就是,在一個多組件構成的應用中,每一個父組件負責管理state並且通過props傳遞給下一層組件。
狀態(state)通過setState方法來更新,來確保UI更新發生。如果有必要state的最終結果值應該被當作 子組件的屬性 傳遞給子組件,在子組件中通過this.props來獲取值。
下面來舉例:
var FilteredList = React.createClass({ //自定義的過濾方法 filteredList: function (event) { var updateList = this.state.initialItems; //根據輸入框的值來過濾出結果 updateList = updateList.filter(function (item) { return item.toLowerCase().search(event.target.value.toLowerCase()) !== -1; }); //將過濾出的值通過setState方法來更新state this.setState({items: updateList}); }, //state 初始化方法 getInitialState: function () { return { initialItems: ["Apples", "Broccoli", "Chicken", "Duck", "Eggs", "Fish", "Granola","Hash Browns"], items: [] } }, //在組件渲染之前執行該方法 componentWillMount: function () { this.setState({items: this.state.initialItems}); }, render: function () { //onChange 事件來執行filteredList方法 //再將更新過的state 作為List組件的屬性傳遞給List組件 return ( <div class="filter-class"> <input type="text" placeholder="Search" onChange={this.filteredList} /> <List items={this.state.items} /> </div> ) } }) var List = React.createClass({ render: function () { //List組件中通過this.props來獲取到FilteredList傳遞進來的值 return ( <ul> { this.props.items.map(function (item) { return <li key={item}>{item}</li> }) } </ul> ) } }); React.render(<FilteredList/>, document.getElementById("mount-point"));
運行結果:
感覺還是不錯的哦
11.總結
以上的都是一些關於react的基礎。有時間,有問題就去查看React API:"http://facebook.github.io/react/docs/top-level-api.html"
最好也去了解下關於jsx:http://facebook.github.io/react/docs/jsx-in-depth.html
下一節,我將翻譯關於學習通過express建立應用,並在服務端使用react渲染,跟前客戶端一樣,然后通過socket.io來使這兩端保持同步。
翻譯不是很好!英語水平有限啊!我會盡量將自己的理解放入進去!
上面的代碼都是我自己運行過的!