React 入门之路
React
React簡介
是由Facebook公司推廣的一套框架,已經(jīng)應(yīng)用instagram等產(chǎn)品
React就是為了提供應(yīng)用程序性能而設(shè)計(jì)的一套框架
在angular中,對dom提供了一些指令,讓dom具有一些功能,例如ng-repeat讓dom具有動態(tài)循環(huán)渲染的功能,ng-show讓dom元素具有動態(tài)顯隱的功能等等
比如將頁面比作一輛汽車,
Angular的實(shí)現(xiàn)就是為汽車添加一些裝飾,增加一些功能,讓汽車看上去很高大尚,這樣勢必要加大油門
React的實(shí)現(xiàn)就是重新制造一輛汽車,是有四個(gè)轱轆,即可啟動,不要很大的油門
React有三大創(chuàng)新
虛擬dom
組件開發(fā)
多端適配
一處開發(fā),處處適用
react在0.13版本之后,做了一個(gè)處理
將react文件分成了兩個(gè)部分
React.js核心庫文件(創(chuàng)建虛擬dom的,核心模塊,寫的應(yīng)用程序可以兼容所有端)
React-dom.js在瀏覽器端渲染虛擬dom
創(chuàng)建虛擬dom
由react對象提供的一個(gè)方法createElement
第一個(gè)參數(shù)表示虛擬dom的名稱,例如div
有時(shí)我們還可以傳遞組件
第二個(gè)參數(shù)是一個(gè)對象,表示虛擬dom中擁有的屬性
從第三個(gè)參數(shù)開始表示該虛擬dom元素的子元素
子元素也要由createElement創(chuàng)建,但是文本節(jié)點(diǎn)可以直接寫
方法的返回值是一個(gè)虛擬dom(js對象)
?
Render
由ReactDOM提供的一個(gè)方法
三個(gè)參數(shù)
1?渲染虛擬dom元素
2?真實(shí)的dom元素
3?渲染完成回調(diào)函數(shù)(不常用)
1// 創(chuàng)建虛擬dom 2var h1 = React.createElement( 3 'h1', 4 { 5 title: '這是標(biāo)題' 6 }, 7 '我是文本內(nèi)容啦啦啦' 8 ) 9// 將h1渲染到頁面中 10ReactDOM.render(h1, document.getElementById('app'), function () { 11 console.log(arguments) 12 console.log(this) })?
組件
在react中定義的一個(gè)虛擬dom很難復(fù)用,所以通常我們將一組虛擬dom定義在組件中來復(fù)用
createClass可以用來創(chuàng)建一個(gè)組件
參數(shù)是一個(gè)對象,用來描述組件的
可以在對象中定義render方法,通過返回值來渲染這組組件
返回值,通常所有虛擬dom都在一個(gè)容器內(nèi)
組件式一個(gè)類,因此組件名稱要以大寫字母開頭
組件要想渲染到頁面中,就要將組件轉(zhuǎn)化成虛擬dom,通過React.createElement方法(由React-dom.js提供)
1var List = React.createClass({ 2 // 通過render渲染頁面 3 render: function () { 4 return ( 5 React.createElement( 6 'ul', 7 null, 8 React.createElement('li', null, '六間房秀場'), 9 React.createElement('li', null, '斗魚TV'), 10 React.createElement('li', null, '美女秀場'), 11 React.createElement('li', null, '秀色直播') 12 ) 13 ) 14 } 15}) 16// 將組件渲染到頁面中 17// 轉(zhuǎn)化組件到虛擬DOM 18var ul = React.createElement(List) ReactDOM.render(ul, document.getElementById('app'))?
JSX語法
我們寫虛擬dom的最大問題,創(chuàng)建一個(gè)虛擬dom成本太高了(寫的太麻煩了),React團(tuán)隊(duì)為了簡化對createElement的書寫,為我們提供了jsx語法
react團(tuán)隊(duì)提供了兩種處理方法
?
第一種,在瀏覽器端編譯?
引入編譯庫,例如browser.js可以對jsx語法編譯
此時(shí)定義的script標(biāo)簽的type類型要定義成text/babel, 在里面可以寫jsx語法
?第二種,在工程化中編譯(最常見的)
編譯jsx語法,跟以前編譯less,sass,stylus很像
首先要獲取這些jsx文件(通常我們將寫jsx語法的文件拓展名改成.jsx)
以fis為例
1fis.match('**.jsx', { 2 // 編譯 3 parser: 'babel2', 4 // 更改后綴名稱 5 rExt: '.js' })?
特殊屬性
?
Class
Class在js中是保留字,因此在react定義虛擬dom的時(shí)候,將class寫成className
?
For (是label元素特有的屬性)
For是js中的關(guān)鍵字,因此在react定義虛擬dom的時(shí)候,將for屬性寫成htmlFor
1var h1 = (<h1 className="red">我是文本內(nèi)容啦啦啦</h1>); 2// 將虛擬dom渲染到頁面中 3ReactDOM.render(h1, document.getElementById('app')) 4 5// 創(chuàng)建一個(gè)組件 6var User = React.createClass({ 7 render: function() { 8 // 返回虛擬dom 9 return ( 10 <div> 11 <label htmlFor="user_name">用戶名</label> 12 <input id="user_name" type="text" /> 13 </div> 14 ); 15 } })?
插值
React支持插值語法,我們在jsx語法中使用,語法是 ?{}
一對{}提供了一個(gè)js環(huán)境,因此我們可以在大括號里面設(shè)置虛擬dom元素的屬性,設(shè)置虛擬dom元素的內(nèi)容
我們可以在插值符號中使用js中的任何表達(dá)式
?
非元素屬性
?
Key?為列表元素定義react-id,綁定id。這樣可以方便獲取頁面中哪些元素更新了,哪些元素需要更新
Render方法的作用域是組件實(shí)例化對象,可以訪問到組件中定義的方法
1createChildList: function () { 2 // 遍歷數(shù)組,處理每一個(gè)成員,然后映射一個(gè)新數(shù)組,就是map方法 3 return data.map(function (value, index) { 4 // 每一個(gè)li要綁定內(nèi)容,還要設(shè)置key 5 return <li key={index}>{value}</li>; 6 }) },屬性
在html中,對于同一類元素來說,之所以展現(xiàn)的樣式不一樣,是因?yàn)樗麄兙哂胁煌膶傩?#xff0c;所以屬性可以讓同一類元素展現(xiàn)出不同的狀態(tài)
同樣的道理,在react中,對于同一個(gè)組件來說,可以創(chuàng)建一組虛擬dom樹,如果想讓虛擬dom樹展現(xiàn)出不同的狀態(tài),我們就要為其添加屬性
在虛擬dom上添加屬性跟在html中元素上添加屬性是一樣的,通過添加一個(gè)屬性實(shí)現(xiàn)(只不過在組件上添加的都是自定義屬性)
我們添加的自定義屬性,會存儲在組件的props屬性中,我們通過this.props可以訪問到里面的數(shù)據(jù)
組件的默認(rèn)屬性我們定義在getDefaultProps中,通過返回值設(shè)置默認(rèn)屬性數(shù)據(jù)
?
1// 創(chuàng)建導(dǎo)航標(biāo)題組件 2var Nav = React.createClass({ 3 // 定義默認(rèn)屬性數(shù)據(jù) 4 getDefaultProps: function () { 5 // 通過返回值定義默認(rèn)屬性數(shù)據(jù) 6 return { 7 data: ['默認(rèn)標(biāo)題'] 8 } 9 }, 10 // 封裝渲染內(nèi)容的方法 11 createChildList: function () { 12 var me = this; 13 // 遍歷this.props.data渲染 14 return this.props.data.map(function (value, index) { 15 return (<a href="" key={index}>{value}{index != me.props.data.length - 1 ? '/' : ''}</a>) 16 }) 17 }, 18 // 通過render方法渲染虛擬dom樹 19 render: function () { 20 return ( 21 <div> 22 {this.createChildList()} 23 </div> 24 ) 25 } 26}) 27var data1 = ['財(cái)經(jīng)', '證券', '理財(cái)']; 28// 渲染 ReactDOM.render(<Nav data={data1} />, document.getElementById('app'))?
樣式
在虛擬dom中我們可以為元素定義樣式
在react中,虛擬dom上不能使用行內(nèi)樣式字符串,行內(nèi)樣式只能定義成對象,Css屬性名稱如果出現(xiàn)多個(gè)單詞,要使用駝峰式命名,例如
border-color => borderColor
還要求瀏覽器前綴第一個(gè)字母要大寫,例如
-webkit-box-shadow ?=> WebkitBoxShadow
在createElement方法中,樣式寫在style中,直接賦值對象,在jsx語法中,樣式寫在style中,要使用插值語法
?
?
1// 定義虛擬dom 2var h1 = React.createElement('h1', { 3 style: { 4 color: 'red', 5 fontSize: '40px' 6 } 7}, '我是文本內(nèi)容啦啦啦'); 8 9// jsx語法,定義虛擬dom 10var h1 = (<h1 style={{ 11 color: 'green', 12 fontSize: '100px' }}>文本內(nèi)容</h1>)?
事件
React中定義事件,跟在html中定義事件很像
在html中定義事件
<button οnclick="console.log('hello')">按鈕</button>
在react中jsx語法中定義事件,跟html中定義事件很像
<button onClick={this.clickBtn}>按鈕</button>
on+事件名稱=回調(diào)函數(shù)?
事件名稱首字母大寫
事件回調(diào)函數(shù)通常綁定組件中的方法
事件回調(diào)函數(shù)不要執(zhí)行(后面不要加())
事件回調(diào)函數(shù)
作用域是組件實(shí)例化對象(可以通過this訪問組件上的方法以及屬性數(shù)據(jù))
可以通過bind方法更改作用域
可以通過bind方法傳遞自定義參數(shù)(很少用)
參數(shù)有三個(gè)
React封裝的事件對象(最常用)
React-id
源生的事件對象
?
?
1var Demo = React.createClass({ 2 // 定義事件回調(diào)函數(shù) 3 clickBtn: function () { 4 console.log(arguments) 5 console.log(this) 6 }, 7 render: function () { 8 return ( 9 <div> 10 <button onClick={this.clickBtn.bind(this, 11)}>這是個(gè)按鈕</button> 11 </div> 12 ) 13 } })?這個(gè)就是參數(shù)
狀態(tài)
狀態(tài)跟屬性一樣都是在組件內(nèi)部存儲數(shù)據(jù)的
屬性是組件外部傳遞的數(shù)據(jù)
狀態(tài)是組件內(nèi)部維護(hù)的數(shù)據(jù)
有狀態(tài)組件以及無狀態(tài)組件
無狀態(tài)組件
對于一個(gè)組件來說,如果組件沒有狀態(tài),也就是說組件式一成不變的,組件在創(chuàng)建之后,不會發(fā)生交互,請求數(shù)據(jù)等等,這類組件叫無狀態(tài)組件,
組件自身不會維護(hù)狀態(tài)
有狀態(tài)組件
對于一個(gè)組件來說,自從創(chuàng)建以后,組件會產(chǎn)生一些交互,請求一些數(shù)據(jù),來完成自身狀態(tài)的更新,這類組件內(nèi)部必須維護(hù)一個(gè)狀態(tài)來存儲這些變化的數(shù)據(jù),這類組件叫有狀態(tài)
組件處于哪種狀態(tài)由其自身存儲的數(shù)據(jù)決定,組件的存儲跟屬性一樣,在組件實(shí)例化對象中有個(gè)state屬性,就是用來存儲狀態(tài)數(shù)據(jù)
初始化狀態(tài)用getInitialState方法定義,通過return?將初始化狀態(tài)的數(shù)據(jù)返回
修改狀態(tài),用setState方法
參數(shù)是一個(gè)對象,對象中的屬性就是即將修改的狀態(tài)
狀態(tài)或者屬性的改變都會觸發(fā)render方法的執(zhí)行,這句話很重要
最后是一個(gè)小小的換膚案例
html代碼
<html lang="en"> <head><meta charset="UTF-8"><title></title><link rel="stylesheet" type="text/css" href="less/15.less"> </head> <body><div id="app"></div> <script type="text/javascript" src="lib/react.js"></script> <script type="text/javascript" src="lib/react-dom.js"></script> <script type="text/javascript" src="lib/jquery.js"></script> <script type="text/javascript" src="code/15.jsx"></script> </body> </html>less代碼
?
* {list-style: none;margin: 0;padding: 0; } body {background-repeat: no-repeat;background-attachment: fixed;background-position: center 0;background-size: cover; } #app {width: 1118px;margin: 50px auto;ul {margin-right: -10px;}li {width: 178px;margin-right: 10px;float: left;margin-bottom: 10px;}p {line-height: 30px;text-align: center;}img {cursor: pointer;} }jsx代碼
// 定義換膚組件 var Skin = React.createClass({// 初始化狀態(tài)數(shù)據(jù)getInitialState: function () {return {list: []}},// 定義事件回調(diào)函數(shù)chooseImage: function (e) {// 獲取li元素var li = e.currentTarget;// 獲取var id = li.getAttribute('data-id')// 用id獲取大圖片的地址,渲染bodydocument.body.style.backgroundImage = 'url(img/skin/big_' + id + '.jpg)'// console.log(id)},// 定義渲染列表的方法getImageList: function () {var me = this;// 通過狀態(tài)來渲染了return this.state.list.map(function (obj, index) {return (<li key={index} data-id={obj.id} onClick={me.chooseImage}><img src={"img/skin/" + obj.src} alt=""/><p>{obj.title}</p></li>)})},render: function () {return (<ul>{this.getImageList()}</ul>)},// 發(fā)送請求獲取數(shù)據(jù)componentDidMount: function () {var me = this;$.get('data/skin.json', function (res) {// 請求成功,更新狀態(tài)數(shù)據(jù)if (res && res.errno === 0) {me.setState({list: res.data})}})} }) // 渲染到頁面中 ReactDOM.render(<Skin />, document.getElementById('app'))轉(zhuǎn)載于:https://www.cnblogs.com/libin-1/p/6550921.html
總結(jié)
以上是生活随笔為你收集整理的React 入门之路的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JS补充
- 下一篇: Sqoop找不到主类 Error: Co