React
React 是由Facfbook維護的一套框架,並且引用到instagram
React只是我們熟悉MVC框中的V層,只是視圖層面的一個框架,只有倆個半api(createClass,createElement,render)
React與Angular的區別
React: 性能好,單向數據綁定,不是完整的框架。
Angular: 性能較差,雙向數據綁定,是一套完整的框架
https://www.zhihu.com/question/23444167
為什么React的性能要好?
因為React做了倆點優化。
1、 在渲染時性能的優化
React是創建了一個虛擬dom,這個dom不是真正頁面中的dom元素,它實質上是一個js對象,用js對象存儲dom上的信息,因此比真是的dom小得多,因為他只記錄的一些必要的信息。
操作一個虛擬dom需要的性能要遠小於操作一個真實dom的性能,在前端開發一個web應用與開發一個網站不同,web應用通常是一個單頁面,因此每次做一些交互會涉及各種dom操作,因此無節制的操作dom嚴重影響了頁面的性能,但是我們只是操作虛擬dom會很好的降低對性能的消耗,在必要的時候將視圖渲染到頁面之中。
2、 在開發時的優化
React的開發理念是創建一個虛擬dom,而虛擬dom是一個js對象,它不是基於某一個端,比如真實的dom可能需要瀏覽器環境,它是基於web端的,所有通過React開發出來的組件可以用於任何平台,比如,服務器端,web端,ios端,android端
將虛擬dom引用到不同的端上需要不同的插件,然后調用不同的render方法。
|
學習React
- 認識React
- 組件
- Jsx的引用
- 插值符號
- 組件的屬性
- 組件的樣式
- 組件的事件
- 組件的生命周期
- React的ref屬性
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="utf-8"/>
<title>hello react!</title>
</head>
<body>
<div id="root"></div>
<script src="js/react.min.js"></script>
<script src="js/react-dom.min.js"></script>
<script src="js/browser.min.js"></script>
<script type="text/babel">
console.dir(document.body)
console.log(<h1>hello,react!</h1>);
ReactDOM.render(
<h1>hello,react!</h1>,
document.getElementById("root")
);
</script>
</body>
</html>
認識React
1、 createElement()是用來創建虛擬dom的方法,他有一些參數
第一個參數表示:虛擬dom的名稱,通常是一些標簽名稱,比如:div a p span
第二個參數表示:虛擬dom的屬性,比如:className id title value
從第三個參數開始:表示虛擬dom的子節點。
2、 render()是用來將虛擬dom渲染到頁面的方法
第一個參數表示:虛擬dom’元素
第二個參數表示:真是的dom元素
第三個參數表示:一個回調函數
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8"/> <title>非jsx編譯時的創建虛擬dom</title> </head> <body> <div id="root"></div> <script src="js/react.min.js"></script> <script src="js/react-dom.min.js"></script> <!--<script src="js/browser.min.js"></script>--> <script type="text/javascript"> var virtualDOM=React.createElement( "ul", null, "我是ul", React.createElement( "li", null, "我是li1" ), React.createElement( "li", null, "我是li2" ), React.createElement( "li", null, "我是li3" ) ); ReactDOM.render( virtualDOM, document.getElementById("root") ); </script> </body> </html>
組件
1組件是做什么的?
如果一個虛擬dom復用多次的時候,通常我們將它封裝在一個組件當中,通常用組件封裝一組虛擬dom,這一組虛擬dom通常稱他為虛擬dom樹。
2組件如何創建?
createClass()是創建組件的方法,組件名稱需要大寫,參數是一個對象,對象中的屬性和方法是對組件的說明:
屬性1:render()方法,它是將組件中的虛擬dom輸出,所以我們將虛擬dom定義在render()中並返回一個虛擬dom樹。
Jsx語法引用
1.為什么引用jsx語法?
解決了創建虛擬dom成本過大的問題。
2.什么是jsx語法?
簡單地說,就是jsx語法讓我們可以再js中寫xhtml
3.如何引用jsx語法?
- 引用一個庫文件browser.min.js或者browser.js都行
- 在編寫React的script標簽的type屬性為text/babel
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8"/> <title></title> </head> <body> <div id="root"></div> <script src="js/react.min.js"></script> <script src="js/react-dom.min.js"></script> <script src="js/browser.min.js"></script> <script type="text/babel"> var Ul=React.createClass({ render:function(){ return ( <ul name="哈哈"> 我是ul1 <li>我是li1</li> <li>我是li2</li> <li>我是li3</li> </ul> ) } }); var ul=React.createElement(Ul); ReactDOM.render( ul, document.getElementById("root") ); </script> </body> </html>
插值符號
- 什么是插值符號?
插值符號簡單的說就是{},在jsx語法中書寫注釋需要寫在插值符號中。
組件的屬性
- props屬性
1.props屬性是什么?
和html給標簽添加一個類一樣,對於完全一致的統一組件他們暫時的樣式是完全一致的,給其中一個添加一些屬性,此時這個組件展示的結果就可能會不同,所以react提出了組件屬性的概念。
2.如何添加props屬性?
在jsx中為組件添加屬性跟html中添加屬性的方法是一模一樣的,只不過react組件可以執行插值(就是可以將js中數據添加到組件中)
- state屬性
1什么是無狀態組件?
如果組建創建並渲染到頁面中以后不會再更改,也就是說組件式一成不變的,這類組件我們只需要在創建之初為其添加一些屬性即可完成對央視行為的控制,這類組件以后再也不會改變了,我們稱之為無狀態組件(stateless組件),簡單地說,就是不會與用戶產生交互,或者發送異步請求。
2.什么是有狀態組件?
如果組建創建后會根據用戶的不同交互產生不同的行為(如更改樣式),這一類組件我們稱之為有狀態,組建處於那種狀態是由用戶決定。
3.state屬性是什么?
組件內部通常會維護一個狀態,這個屬性就是state,和props一樣,我們都可以更改他們,但是我們說props是在組建創建是傳遞的屬性值不同而決定的,因此以后通常是更改不了的(除了子組件)state通常是在產生交互時候改變的,一次她的改變永遠伴隨着一個交互,每次state,props的改變都會執行一次render方法來重新渲染組件,組件是否更改是由虛擬dom有沒有改變決定,如果虛擬dom改變了組件就會渲染。
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8"/> <title>組件復用</title> </head> <body> <div id="root1"></div> <div id="root2"></div> <script src="js/react.min.js"></script> <script src="js/react-dom.min.js"></script> <script src="js/browser.min.js"></script> <script type="text/babel"> var Ul=React.createClass({ setLi:function(){ return this.props.liData.map(function(value,index){ return ( <li key={index}>{value}</li> ) }) }, render:function(){ return ( <ul>{this.setLi()}</ul> ) } }); ReactDOM.render( <Ul liData={[1,2,3]}/>, document.getElementById("root") ); ReactDOM.render( <Ul liData={[1,2,3]}/>, document.getElementById("root1") ); </script> </body> </html>
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8"/> <title>復合組件</title> <script src="js/react.min.js"></script> <script src="js/react-dom.min.js"></script> <script src="js/browser.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> var SuperComponent=React.createClass({ render:function(){ return ( <div> <SupComponent name={this.props.name}/> </div> ) } }); var SupComponent=React.createClass({ render:function(){ return ( <h1>{this.props.name}</h1> ); } }); ReactDOM.render( <SuperComponent name="浮沉"/>, document.getElementById("root") ); </script> </body> </html>
組件的樣式
1.樣式style屬性的值只能是對象,不能為style添加字符串的值
2.Font-size這類要用駝峰式fontSize
3.Css3前綴的屬性第一個字母要大寫WebkitTransform
4.組件中定義一個虛擬dom我們都要用對象,並且可以使用變量,變量當中可以使用表達式。
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8"/> <title>帶樣式的組件</title> <style> .style{background-color: #000000;} </style> </head> <body> <div id="root"></div> <script src="js/react.min.js"></script> <script src="js/react-dom.min.js"></script> <script src="js/browser.min.js"></script> <script type="text/babel"> var HelloMessage=React.createClass({ render:function(){ var style={ color:"red" } return ( <div className="style"> <h1 style={style}>Hello,React!</h1> <h1 style={{color:"green"}}>Hello,Angular!</h1> </div> ) } }) ReactDOM.render( <HelloMessage/>, document.getElementById("root") ); </script> </body> </html>
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8"/> <title>帶事件的組件</title> <script src="js/react.min.js"></script> <script src="js/react-dom.min.js"></script> <script src="js/browser.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> var LikeButton=React.createClass({ getInitialState:function(){ return {liked:false}; }, handleClick:function(e){ this.setState({liked:!this.state.liked}); }, render:function(){ var text=this.state.liked?"喜歡":"不喜歡"; return ( <p onClick={this.handleClick}> 我{text}react! </p> ); } }); ReactDOM.render( <LikeButton/>, document.getElementById("root") ); </script> </body> </html>
React組件生命周期
組建的生命周期可分成三個狀態:
Mounting:以插入真是DOM
Updating:正在被重新渲染
Unmounting:已移除真實DOM
生命周期的方法有:
componentWillMount:在渲染前調用,在客戶端也在服務端
componentDidMount:在第一次渲染后調用,只在客戶端。之后組件已經生成了對應的DOM結構,可以通過this.getDOMNode()來進行訪問。如果你想和其他javascript框架一起使用,可以在這個方法中調用setTImeout,setInterval或者發送Ajax請求等操作(防止異步操作阻塞UI)。
ComponentWIllReceiveProps在組建接收到一個props時被調用。這個方法在初始化render時不會被調用。
shouldComponentUpdate返回一個布爾值。在組件接收到新的props或者state時被調用。在初始化時或者使用forceUpdate時不被調用
componentDIdupdate: 在組件完成更新后立即調用。在初始化時不會被調用。
componentWillUnmount:在組件從DOM中移出的時候激勵被調用。
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8"/> <title>生命周期</title> <script src="js/react.min.js"></script> <script src="js/react-dom.min.js"></script> <script src="js/browser.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> var Hello=React.createClass({ getInitialState:function(){ return {opacity:1} }, componentDidMount:function(){ this.timer=setInterval(function(){ var opacity=this.state.opacity; opacity-=.05; if(opacity<0.1) { opacity=1; } this.setState({opacity:opacity}); }.bind(this),100); }, render:function(){ return ( <div style={{opacity:this.state.opacity}}> Hello React! </div> ) } }); ReactDOM.render( <Hello name="world"/>, document.getElementById("root") ); </script> </body> </html>
React Refs
React 支持一種非常特殊的屬性 Ref ,你可以用來綁定到 render() 輸出的任何組件上。
這個特殊的屬性允許你引用 render() 返回的相應的支撐實例( backing instance )。這樣就可以確保在任何時間總是拿到正確的實例。
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8"/> <title>ref的使用</title> <script src="js/react.min.js"></script> <script src="js/react-dom.min.js"></script> <script src="js/browser.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> var MyComponent = React.createClass({ handleClick: function() { // 使用原生的 DOM API 獲取焦點 this.refs.myInput.focus(); }, render: function() { // 當組件插入到 DOM 后,ref 屬性添加一個組件的引用於到 this.refs return ( <div> <input type="text" ref="myInput" /> <input type="button" value="點我輸入框獲取焦點" onClick={this.handleClick} /> </div> ); } }); ReactDOM.render( <MyComponent />, document.getElementById('root') ); </script> </body> </html>