React 入门之路
React
React簡介
是由Facebook公司推廣的一套框架,已經應用instagram等產品
React就是為了提供應用程序性能而設計的一套框架
在angular中,對dom提供了一些指令,讓dom具有一些功能,例如ng-repeat讓dom具有動態循環渲染的功能,ng-show讓dom元素具有動態顯隱的功能等等
比如將頁面比作一輛汽車,
Angular的實現就是為汽車添加一些裝飾,增加一些功能,讓汽車看上去很高大尚,這樣勢必要加大油門
React的實現就是重新制造一輛汽車,是有四個轱轆,即可啟動,不要很大的油門
React有三大創新
虛擬dom
組件開發
多端適配
一處開發,處處適用
react在0.13版本之后,做了一個處理
將react文件分成了兩個部分
React.js核心庫文件(創建虛擬dom的,核心模塊,寫的應用程序可以兼容所有端)
React-dom.js在瀏覽器端渲染虛擬dom
創建虛擬dom
由react對象提供的一個方法createElement
第一個參數表示虛擬dom的名稱,例如div
有時我們還可以傳遞組件
第二個參數是一個對象,表示虛擬dom中擁有的屬性
從第三個參數開始表示該虛擬dom元素的子元素
子元素也要由createElement創建,但是文本節點可以直接寫
方法的返回值是一個虛擬dom(js對象)
?
Render
由ReactDOM提供的一個方法
三個參數
1?渲染虛擬dom元素
2?真實的dom元素
3?渲染完成回調函數(不常用)
1// 創建虛擬dom 2var h1 = React.createElement( 3 'h1', 4 { 5 title: '這是標題' 6 }, 7 '我是文本內容啦啦啦' 8 ) 9// 將h1渲染到頁面中 10ReactDOM.render(h1, document.getElementById('app'), function () { 11 console.log(arguments) 12 console.log(this) })?
組件
在react中定義的一個虛擬dom很難復用,所以通常我們將一組虛擬dom定義在組件中來復用
createClass可以用來創建一個組件
參數是一個對象,用來描述組件的
可以在對象中定義render方法,通過返回值來渲染這組組件
返回值,通常所有虛擬dom都在一個容器內
組件式一個類,因此組件名稱要以大寫字母開頭
組件要想渲染到頁面中,就要將組件轉化成虛擬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// 轉化組件到虛擬DOM 18var ul = React.createElement(List) ReactDOM.render(ul, document.getElementById('app'))?
JSX語法
我們寫虛擬dom的最大問題,創建一個虛擬dom成本太高了(寫的太麻煩了),React團隊為了簡化對createElement的書寫,為我們提供了jsx語法
react團隊提供了兩種處理方法
?
第一種,在瀏覽器端編譯?
引入編譯庫,例如browser.js可以對jsx語法編譯
此時定義的script標簽的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的時候,將class寫成className
?
For (是label元素特有的屬性)
For是js中的關鍵字,因此在react定義虛擬dom的時候,將for屬性寫成htmlFor
1var h1 = (<h1 className="red">我是文本內容啦啦啦</h1>); 2// 將虛擬dom渲染到頁面中 3ReactDOM.render(h1, document.getElementById('app')) 4 5// 創建一個組件 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語法中使用,語法是 ?{}
一對{}提供了一個js環境,因此我們可以在大括號里面設置虛擬dom元素的屬性,設置虛擬dom元素的內容
我們可以在插值符號中使用js中的任何表達式
?
非元素屬性
?
Key?為列表元素定義react-id,綁定id。這樣可以方便獲取頁面中哪些元素更新了,哪些元素需要更新
Render方法的作用域是組件實例化對象,可以訪問到組件中定義的方法
1createChildList: function () { 2 // 遍歷數組,處理每一個成員,然后映射一個新數組,就是map方法 3 return data.map(function (value, index) { 4 // 每一個li要綁定內容,還要設置key 5 return <li key={index}>{value}</li>; 6 }) },屬性
在html中,對于同一類元素來說,之所以展現的樣式不一樣,是因為他們具有不同的屬性,所以屬性可以讓同一類元素展現出不同的狀態
同樣的道理,在react中,對于同一個組件來說,可以創建一組虛擬dom樹,如果想讓虛擬dom樹展現出不同的狀態,我們就要為其添加屬性
在虛擬dom上添加屬性跟在html中元素上添加屬性是一樣的,通過添加一個屬性實現(只不過在組件上添加的都是自定義屬性)
我們添加的自定義屬性,會存儲在組件的props屬性中,我們通過this.props可以訪問到里面的數據
組件的默認屬性我們定義在getDefaultProps中,通過返回值設置默認屬性數據
?
1// 創建導航標題組件 2var Nav = React.createClass({ 3 // 定義默認屬性數據 4 getDefaultProps: function () { 5 // 通過返回值定義默認屬性數據 6 return { 7 data: ['默認標題'] 8 } 9 }, 10 // 封裝渲染內容的方法 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 = ['財經', '證券', '理財']; 28// 渲染 ReactDOM.render(<Nav data={data1} />, document.getElementById('app'))?
樣式
在虛擬dom中我們可以為元素定義樣式
在react中,虛擬dom上不能使用行內樣式字符串,行內樣式只能定義成對象,Css屬性名稱如果出現多個單詞,要使用駝峰式命名,例如
border-color => borderColor
還要求瀏覽器前綴第一個字母要大寫,例如
-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}, '我是文本內容啦啦啦'); 8 9// jsx語法,定義虛擬dom 10var h1 = (<h1 style={{ 11 color: 'green', 12 fontSize: '100px' }}>文本內容</h1>)?
事件
React中定義事件,跟在html中定義事件很像
在html中定義事件
<button οnclick="console.log('hello')">按鈕</button>
在react中jsx語法中定義事件,跟html中定義事件很像
<button onClick={this.clickBtn}>按鈕</button>
on+事件名稱=回調函數?
事件名稱首字母大寫
事件回調函數通常綁定組件中的方法
事件回調函數不要執行(后面不要加())
事件回調函數
作用域是組件實例化對象(可以通過this訪問組件上的方法以及屬性數據)
可以通過bind方法更改作用域
可以通過bind方法傳遞自定義參數(很少用)
參數有三個
React封裝的事件對象(最常用)
React-id
源生的事件對象
?
?
1var Demo = React.createClass({ 2 // 定義事件回調函數 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)}>這是個按鈕</button> 11 </div> 12 ) 13 } })?這個就是參數
狀態
狀態跟屬性一樣都是在組件內部存儲數據的
屬性是組件外部傳遞的數據
狀態是組件內部維護的數據
有狀態組件以及無狀態組件
無狀態組件
對于一個組件來說,如果組件沒有狀態,也就是說組件式一成不變的,組件在創建之后,不會發生交互,請求數據等等,這類組件叫無狀態組件,
組件自身不會維護狀態
有狀態組件
對于一個組件來說,自從創建以后,組件會產生一些交互,請求一些數據,來完成自身狀態的更新,這類組件內部必須維護一個狀態來存儲這些變化的數據,這類組件叫有狀態
組件處于哪種狀態由其自身存儲的數據決定,組件的存儲跟屬性一樣,在組件實例化對象中有個state屬性,就是用來存儲狀態數據
初始化狀態用getInitialState方法定義,通過return?將初始化狀態的數據返回
修改狀態,用setState方法
參數是一個對象,對象中的屬性就是即將修改的狀態
狀態或者屬性的改變都會觸發render方法的執行,這句話很重要
最后是一個小小的換膚案例
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({// 初始化狀態數據getInitialState: function () {return {list: []}},// 定義事件回調函數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;// 通過狀態來渲染了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>)},// 發送請求獲取數據componentDidMount: function () {var me = this;$.get('data/skin.json', function (res) {// 請求成功,更新狀態數據if (res && res.errno === 0) {me.setState({list: res.data})}})} }) // 渲染到頁面中 ReactDOM.render(<Skin />, document.getElementById('app'))轉載于:https://www.cnblogs.com/libin-1/p/6550921.html
總結
以上是生活随笔為你收集整理的React 入门之路的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JS补充
- 下一篇: Sqoop找不到主类 Error: Co