先看個簡單的例子:數組
var HelloWorld = React.createClass({ render: function () { return ( <div data-title={this.props.title}>{this.props.content}</div> ) } }); React.render( <HelloWorld title="this is title" content="this is content"/>, document.body );
看代碼就很容易理解:經過this.props咱們能夠拿到組件使用時的屬性。稍微改變下代碼,咱們打印出this.props瞅瞅:瀏覽器
var HelloWorld = React.createClass({ render: function () { return ( <div data-title={this.props.title}>{JSON.stringify(this.props)}</div> ) } }); React.render( <HelloWorld title="this is title" content="this is content"/>, document.body );
瀏覽器頁面效果:服務器
能夠看出this.props就是組件的屬性集合,稍微改下代碼,再來看看:函數
var HelloWorld = React.createClass({ render: function () { return ( <div>{JSON.stringify(this.props)}</div> ) } }); React.render( <HelloWorld title="this is title"> <span>1</span> <span>2</span> </HelloWorld>, document.body );
瀏覽器頁面效果:this
這個時候多了一個children的屬性,React將組件的子節點封裝到了children屬性中,若是想獲取到子節點的內容,能夠這麼寫:spa
var HelloWorld = React.createClass({ render: function () { return ( <div> { this.props.children.map(function (child) { return child; })} </div> ) } }); React.render( <HelloWorld title="this is title"> <span>1</span> <span>2</span> </HelloWorld>, document.body );
當子節點只有一個的時候直接經過this.props.children獲取子節點。當子節點的個數大於1,this.props.children是一個數組。3d
綜上咱們能夠看出,React將節點屬性和子節點都封裝到props當中,咱們能夠經過this.props獲取到。在React的設定中,props是不可變的,當props屬性肯定後,咱們不該該再去手動修改它。代理
看下這個代碼:code
var Hello = React.createClass({ render: function () { return ( <div></div> ) } }); React.render( <Hello> <p>content</p> </Hello>, document.body );
咋一看是否是以爲頁面渲染出來應該是這個效果:blog
<div> <p>content</p> </div>
實際上渲染出來是這樣的:
<div></div>
看頁面的渲染效果:咱們要找到根節點,關注它的render方法的返回值。至於使用時的嵌套結構,看完props應該明白,這些都是組件屬性,想要使用的話,請經過this.props.children.
state是同UI交互最重要的屬性,看個簡單的例子,點擊按鈕,切換按鈕的顏色:
var ColorButton = React.createClass({ getInitialState: function () { return {bColor: 'green'}; }, render: function () { return ( <button onClick={this.handleClick} style={{backgroundColor: this.state.bColor}}>click</button> ) }, handleClick: function (event) { this.setState({bColor: this.state.bColor === 'green' ? 'red' : 'green'}); } }); React.render( <ColorButton />, document.body );
getInitialState是用來初始化state,handleClick是用來處理咱們點擊事件的。
React實現了本身的一套事件代理和處理機制,這套機制是符合W3C標準的。經過這套機制,React有兩個很重要的特色:
全部的事件處理函數當中的this指向組件的實例。若是想要拿到當前操做的DOM,經過參數event獲取。
var ColorButton = React.createClass({ getInitialState: function () { return {name: 'button'}; }, render: function () { return ( <button onClick={this.handleClick}>click</button> ) }, handleClick: function (event) { console.log(this.state); console.log(event.target); } }); React.render( <ColorButton />, document.body );
React並無將事件處理添加到相應的每一個節點上。當React啓動時,在根節點上監聽全部的事件,並管理事件到相應節點的映射。當組件mounted或者unmounted時,事件將會被添加到映射關係或者被刪除。我感受,有點jQuery的事件代理的意思:
#糟糕的寫法 $('li').on('click', function () { //todo }); //好點的寫法 $('ul').on('click', 'li', function () { //todo });
React將UI簡單的看做狀態機。看UI看做各類各樣的狀態,並在各類狀態間切換,很容易保持UI的一致性。在React中,你只要改變組件的狀態,就會從新渲染UI,React會在最有效的方式下更新DOM。
經過調用setState(data, callback)方法,改變狀態,就會觸發React更新UI。大部分狀況下,咱們不須要提供callback函數。React會自動的幫咱們更新UI。
後面在好好看看這個callback的功能和調用時機。
大部分的組件應該從props屬性中獲取數據並渲染。但有的時候組件得相應用戶輸入,同服務器交互,這些狀況下會用到state。React的官方說法是:儘量的保持你的組件無狀態化。爲了實現這個目標,得保持你的狀態同業務邏輯分離,並減小冗餘信息,儘量保持組件的單一職責。
React官方推薦的一種模式就是:構建幾個無狀態的組件用來渲染數據,在這些之上構建一個有狀態的組件同用戶和服務交互,數據經過props傳遞給無狀態的組件。個人理解大概就是這樣:
var RenderComponent = React.createClass({ render: function () { return ( <ul> { this.props['data-list'].map(function (item) { return (<li>{item}</li>) }) } </ul> ) } }); var StateComponent = React.createClass({ getInitialState: function () { return {list: ['xxx', 'yyy']}; }, render: function () { return ( <div> <button onClick={this.handleClick}>click</button> <RenderComponent data-list={this.state.list}/> </div> ) }, handleClick: function () { this.setState({list: [1, 2, 3]}); } }); React.render( <StateComponent />, document.body );
UI交互會致使改變的數據。
state應保含最原始的數據,好比說時間,格式化應該交給展示層去作。
組件應在render方法裏控制。