這是React分類下的第一篇文章,是在瞭解了一些基本面後,看Tyler文章,邊看邊理解邊寫的。react
React能夠看作是MVC中的V,關注的是視圖層。React的組件就像Angular的Directive,包括了HTML,CSS,JS以及相關數據等。React的組件被定義在了以"JSX"爲後綴的文件中,這些JSX文件會被最終編譯成Javascript文件。數組
來看一個最基本的寫法:app
var HelloWorld = React.createClass({ render: function(){ return ( <div> Hello World! </div> ) } }); ReactDOM.render(<HelloWorld />, document.getElementBy('app'));
以上,咱們能夠了解到:dom
React.createClass
用來建立組件,接收一個object,render字段必須有ReactDOM.render
來渲染組件,該方法接收2個參數,一個參數表明組件,另外一個表明渲染的位置<div>Hello World!</div>
和一般的HTML代碼不同,是放在以jsx爲後綴的文件中的,最終會被轉換成一個Javascript對象,最終React會建立一個"virtual DOM",React會經過React.createElement("div", null, "Hello Wolrd")
建立虛擬的DOM。→ 檢查數據發生變化的部分
→ 從新渲染virutal DOM
→ 與上一次的virtual DOM進行比較
→ 在實際DOM上只更新發生變化的部分ide
var HelloUser = React.createClass({ getInitialState: function(){ return { username: 'firstusername' } }, render: function(){ return ( <div> Hello {this.state.username} </div> ) } });
getInitialState
方法返回object對象,爲state中的字段賦值this.state.字段名
來獲取字段狀態setState
雖然在上面沒有說起,但這個方法時被用來真正設置組件狀態的。並且這個setState
方法是最經常使用的,當頁面有數據變化,Reacct會觸發setState
方法,渲染virtual DOM,與上一次的virtual DOM進行比較,最後更新發生變化的部分。2.1 經過事件改變狀態函數
以上,是經過getInitialState
方法設置了一個初始狀態,如何經過事件來觸發改變狀態呢?好比有一個<input>
,經過它的onChange
方法來觸發改變狀態。ui
var HelloUser = React.creatClass({ getInitialState: function(){ return { username: 'darren' } }, handleChange: function(e){ this.setState({ usename: e.target.value }); }, render: function(){ return ( <div> Hello {this.state.username}<br/> Change Name:<input type="text" value={this.state.username} onChange={this.handleChange}> </div> ) } });
handleChange
方法中,經過setState
改變變量的狀態,接着,React渲染一個新的virtual DOM, 與上一次的virtual DOM比較差別,最後只更新發生變化的那部分DOMonChange
方法用來觸發事件2.2 嵌套組件的狀態傳遞this
如今,咱們知道了如何設置組件的初始狀態,也知道如何如何設置組件的狀態,如今來到另一個話題:當主鍵有嵌套的時候,如何把父組件的狀態傳遞給子組件呢?code
先來看沒有組件嵌套的狀況:component
var HelloUser = React.createClass({ render: function(){ return ( <div> Hello, {this.props.name}</div> ) } }); ReactDOM.render(<HelloUser name="darren" />, document.getElementById('app'));
<HelloUser />
,組件中的變量,好比這裏的name字段,在jsx語法中是以屬性名存在的,好比這裏的<HelloUser name="darren">
<HelloUser name="darren" />
就是須要渲染的組件,HelloUser就是組件的名稱,給name賦的值最終賦值給了props屬性再來看存在組件嵌套的狀況下,如何傳遞State。
被嵌套的組件:
var ShowList = React.createClass({ render: function(){ var listItems = this.props.names.map(function(friend){ return <li>{{friend}}</li>; }); return ( <div> <h3>Friends</h3> <ul> {listItems} </ul> </div> ) } });
以上,ShowList組件的視圖渲染須要外界給names字段賦上數組。也就是<ShowList names=... />
中names屬性須要賦值。從哪裏賦值呢?能夠從嵌套組件的state中獲取。
好,那就來到嵌套組件:
var ParentContainer = React.createClass({ getIntitialState: function(){ return { name: 'darren', friends:['a','bob'] } }, render: function(){ return ( <div> <h3>Name: {this.state.name}</h3> <ShowList names={this.state.friends}> </div> ) } });
getIntitialState
中返回對象的各個字段是放在了state中的如今,組件看起來就像C#中對類的封裝。React的組件是否和C#中的類有更多的類似性呢?
假設,在顯示朋友列表的頁面再增長一塊區域,用來添加朋友信息。那,咱們有必要爲這一塊添加的區域定義一個組件:
var AddFriend = React.createClas({ getIntialState: function(){ return { newFriend: '' } }, updateNewFriend: function(e){//更新就是爲state的newFriend字段賦上當前的值 this.setState({ newFriend: e.target.value }); }, handleAddNew: function(){ this.props.addNew(this.state.newFriend); this.setState({ newFriend: '' }); }, render: function(){ return ( <div> <input type="text" value={this.state.newFriend} onChange={this.updateNewFriend} /> <button onClick={this.handleAddNew}>Add Friend</button> </div> ) } });
<AddFriend addNew={...} />
這樣的形式呈現以上的AddFriend組件是也是一個被嵌套組件,它和ShowList組件被一塊兒嵌套在ParentContainer這個組件中。
因而,就來到了ParentContainer這個組件。
var ParentContainer = React.createClass({ getInitialState: function(){ return { name: 'darren', friends: ['a','b'] } }, addFriend: function(friend){ this.setState({ this.setState({ friends: this.state.friends.concat([friend]) }); }); }, render: function(){ return ( <div> <h3>Name: {this.state.name}</h3> <AddFriend addNew={this.addFriend} /> <ShowList names={this.state.friends} /> </div> ) } });
被嵌套組件所須要的,都經過嵌套組件的state或函數得到。
2.3 設置組件的屬性類型
在上面的AddFriend組件中,button是這樣的:<button onClick={this.handleAddNew}>Add Friend</button>
,button的點擊事件由handleAddNew函數決定,而handleAddNew函數由this.props.addNew(this.state.newFriend)
所決定,addNew函數是props屬性的函數類型字段,是否能夠定義呢?答案是能夠。
var AddFriend = React.createClas({ getIntialState: function(){ return { newFriend: '' } }, propTypes: { addNew: React.PropTypes.func.isRequired }, updateNewFriend: function(e){//更新就是爲state的newFriend字段賦上當前的值 this.setState({ newFriend: e.target.value }); }, handleAddNew: function(){ this.props.addNew(this.state.newFriend); this.setState({ newFriend: '' }); }, render: function(){ return ( <div> <input type="text" value={this.state.newFriend} onChange={this.updateNewFriend} /> <button onClick={this.handleAddNew}>Add Friend</button> </div> ) } });
組件的生命週期又是怎樣的呢?
var FriendsConainer = React.createClass({ getInitialState: function(){ alert('getInitialState'); return { name: 'darren' } }, componentWillMount: function(){}, componentDidMount: function(){}, componentWillReceiveProps: function(nextProps){}, componentWillUnmount: function(){}, render: function(){ return ( <div> Hello, {this.state.name} </div> ) } });