1、什麼是Reacthtml
React: A JAVASCRIPT LIBRARY FOR BUILDING USER INTERFACESreact
上面的話直譯過來就是,React是一個用於構建用戶界面的JavaScript庫。git
React起源於Facebook內部項目,後來以爲不錯,在2013年6月開源。github
2、學習React算法
我學習的時候是基於 React-Demos 這個阮一峯博客上寫的Demo庫以及他的博客學習的,基本上跟着Demo跑一次下來就差很少入門了。前提是你對JavaScript和DOM有必定的瞭解。數組
3、安裝服務器
1.直接到官網下載數據結構
2.看着React-Demos學習的話,React-Demos中就自帶了React源碼,直接git clone或者下載zip壓縮包學習
4、HelloWorldui
下面是使用React網頁的基本結構
<!DOCTYPE html> <html> <head> <script src="../build/react.js"></script> <script src="../build/JSXTransformer.js"></script> </head> <body> <div id="helloworld"></div> <script type="text/jsx"> // your code React.render( <h1>Hello, World!</h1>, document.getElementById('helloworld') ); </script> </body> </html>
注意:
1.最後的script標籤的type屬性是「text/jsx」。由於React獨有的JSX語法與JacaScript不兼容,使用JSX的地方都有顯示代表type屬性爲"text/jsx"。
2.React提供的兩個庫react.js和JSXTransformer.js都必須首先加載。JSXTransformer.js的做用是件JSX語法轉爲JavaScript語法,這一步實際應該放到服務器完成,由於很是耗時間。
上面的代碼中用到了React.render方法,這是React最基本的方法,用於將模板轉爲HTML語言並插入指定的DOM節點。
咱們看到代碼中,HTML語言直接寫在JavaScript語言中,沒有任何引號,這是JSX語法,容許HTML與JavaScript混寫。
5、JSX語法
把上面的HelloWorld代碼修改一下。
<!DOCTYPE html> <html> <head> <script src="../build/react.js"></script> <script src="../build/JSXTransformer.js"></script> </head> <body> <div id="helloJSX"></div> <script type="text/jsx"> // your code var names = ['John', 'Amin', 'Ann']; React.render( <div> { names.map(function (name) { return <h1>Hello, {name}!</h1> }) } </div>, document.getElementById('helloJSX') ); </script> </body> </html>
上面這種像XML的語法叫JSX語法。
在JSX語法中,遇到HTML標籤(以<開頭)就用HTML規則解析,遇到代碼塊(以{開頭)就用JavaScript規則解析。
上面代碼運行出來就是id爲helloworld的div下再嵌套着一個div,而後再嵌套三個h1標題。
JSX還容許在模板中直接插入JavaScript變量,變量是數組就展開數組成員。
<!DOCTYPE html> <html> <head> <script src="../build/react.js"></script> <script src="../build/JSXTransformer.js"></script> </head> <body> <div id="helloArray"></div> <script type="text/jsx"> // your code var arr = [ <h1>Hello, world!</h1>, <h2>Hello, Amin!</h2>, <h3>React is awesome</h3> ]; React.render( <div>{arr}</div>, document.getElementById('helloArray') ); </script> </body> </html>
上面代碼會在id爲helloArray的div下嵌套三個套着div的標題。
我原本想看一下若是不想在標題外面再嵌套div要怎麼作,暫時還沒發現。
6、組件(component)
<!DOCTYPE html> <html> <head> <script src="../build/react.js"></script> <script src="../build/JSXTransformer.js"></script> </head> <body> <div id="helloComponent"></div> <script type="text/jsx"> // your code var HelloMessage = React.createClass({ render: function() { return <h1>hello, {this.props.name}</h1>; } }); React.render( <HelloMessage name="John"/>, document.getElementById('helloComponent') ); </script> </body> </html>
React容許代碼封裝成組件,在網頁中插入組件就像插入普通HTML標籤同樣。
React.createClass方法是用來生成一個組件類,上面的HelloMessage就是這個方法生成的一個組件類。在模板插入<HelloMessage />時和插入普通的HTML標籤同樣,可是會自動生成HelloMessage這個組件類的一個實例。在組件類中應該有本身的render方法來輸出組件。
組件能夠加入任意的屬性,和HTML標籤的用法同樣。上面的HelloMessage組件中就有一個name屬性。組件屬性在組件類的this.props對象上能夠獲取。
添加組件屬性的時候須要注意不要和JavaScript保留字衝突。若是要用到class和for應該這麼寫:
var MyComponent = React.createClass({ render: function() { return <div className="first"><span>A Span</span></div>; } });
this.props對象屬性基本上和組件屬性對應,除了this.props.children屬性,它表示的意思是組件的全部子節點。
見下面代碼
<!DOCTYPE html> <html> <head> <script src="../build/react.js"></script> <script src="../build/JSXTransformer.js"></script> </head> <body> <script type="text/jsx"> // your code var NoteList = React.createClass({ render: function() { return ( <ol> { this.props.children.map(function (child) { return <li>{child}</li>; }) } </ol> ); } }); React.render( <NoteList> <span>Hello, world!</span> <span>Hello, Amin!</span> <span>Hello, Ann!</span> </NoteList>, document.body ); </script> </body> </html>
NoteList組件類經過this.props.children讀取NoteList組件實例下的三個span子節點,而後從新進行轉化再插入到body中。
注意子節點必須多於1個,this.props.children纔會是一個數組,當它是數組時才能用map方法,不然會報錯。
咱們須要知道,組件並非真實的DOM節點,它是存在於內存中叫虛擬DOM(virtual DOM)的一種數據結構。組件插入文檔中之後纔會成爲真實的DOM節點。
根據React的diff算法,DOM變更都先在虛擬DOM上發生,而後將發生變更部分反映到真實DOM上。
若是須要從組件中獲取真實DOM節點,須要用到的方法叫React.findDOMNode.
<!DOCTYPE html> <html> <head> <script src="../build/react.js"></script> <script src="../build/JSXTransformer.js"></script> </head> <body> <div id="example"></div> <script type="text/jsx"> // your code var MyComponent = React.createClass({ handleClick: function() { React.findDOMNode(this.refs.myTextInput).focus(); }, render: function() { return ( <div> <input type="text" ref="myTextInput" /> <input type="button" value="Focus the text input" onClick={this.handleClick} /> </div> ); } }); React.render( <MyComponent />, document.getElementById('example') ); </script> </body> </html>
我對上面代碼的理解是,在組件MyComponent的子節點中有一個文本輸入框,用於獲取用戶輸入,onClick綁定的事件是組件中的handleClick,讓文本框得到焦點。
這時就須要得到真實的DOM節點,爲了作到這點,首先文本輸入框要有一個ref屬性,我對ref屬性的理解是經過這個屬性文本輸入框被分配了一個名字,經過this.refs.[refName]就能指向這個虛擬DOM的子節點,最後經過React.findDOMNode方法獲取真實DOM節點。
React把組件當作一個狀態機,一開始有一個初始狀態,組件與用戶互動致使狀態變化的話,會觸發從新渲染UI。
<!DOCTYPE html> <html> <head> <script src="../build/react.js"></script> <script src="../build/JSXTransformer.js"></script> </head> <body> <div id="state"></div> <script type="text/jsx"> // your code var LikeButton = React.createClass({ getInitialState: function () { return {liked: false}; }, handleClick: function (event) { this.setState({liked: !this.state.liked}); }, render: function () { var text = this.state.liked ? 'like' : 'haven\'t liked'; return ( <p onClick={this.handleClick} > You {text} this. Click to toggle. </p> ); } }); React.render( <LikeButton />, document.getElementById('state') ); </script> </body> </html>
上面的效果就是你點擊div裏面的文字會進行切換。
LikeButton組件中的getInitialState方法定義初始狀態,這個對象經過this.state讀取。每次點擊都會致使狀態變化,this.setState方法用於修改狀態值,每次修改以後都會自動調用this.render方法,再次渲染組件。
當組件的特性是會隨着與用戶互動而產生變化時,咱們應該使用this.state,而不是this.props