7.JSX語法 1 <script type="text/babel"> 2 //定義內部標題組件 3 class Welcome extends React.Component { 4 render() { 5 return <h2>Welcome {this.props.name}!</h2>; ...
1. ReactJS是什麼?
1). Facebook開源的一個js庫
2). 一個用於動態構建用戶界面的js庫
2. React的特點
* Declarative(聲明式編碼)
* Component-Based(組件化編碼)
* Learn Once, Write Anywhere(支持客戶端與伺服器渲染)
* 高效
* 單向數據流
3. React高效的原因
1). 虛擬(virtual)DOM, 不總是直接操作DOM
2). 高效的DOM Diff演算法, 最小化頁面重繪
4. 模塊與組件的概念
* 模塊: 向外提供特定功能的js程式, 一般就是一個js文件
作用: 簡化js的編寫, 閱讀, 提高運行效率
* 組件: 用來實現特定功能效果的代碼集合(html/css/js)
作用: 復用, 簡化項目編碼, 提高運行效率
5. 模塊化與組件化
* 模塊化:
當應用的js都以模塊來編寫的, 這個應用就是一個模塊化的應用
* 組件化:
當應用是以多組件的方式實現功能, 這個應用就是一個組件化的應用
6.入門案例
react.js: React的核心庫
react-dom.js: 提供操作DOM的擴展庫
babel.min.js: 解析JSX語法代碼轉為純JS語法代碼的庫
在頁面中導入js
編碼
<script type="text/babel"> //必須用babel
1 <div id="demo"></div> 2 3 <script type="text/javascript" src="../js/react.js"></script> 4 <script type="text/javascript" src="../js/react-dom.js"></script> 5 <script type="text/javascript" src="../js/babel.min.js"></script> 6 <script type="text/babel"> 7 //頁面中的真實容器元素 8 var containDiv = document.getElementById('demo'); 9 //react的虛擬DOM對象 10 var vDom = <div id="demo">Hello, React!</div>; //不是字元串, 不能加引號 11 //將虛擬DOM對象渲染到頁面元素中 12 ReactDOM.render(vDom, containDiv); 13 //頁面結果: <div id="demo"><div id="demo">Hello, React!</div></div> 14 </script>
7.JSX語法
JSX 即JavaScript XML,它是一種在React 組件內部構建標簽的類XML語法,使用JSX可以提高組件的可讀性,因此推薦使用。JSX最終會被轉換為JavaScript。
1⃣️React組件只能渲染一個根節點,這是由於js的特性,即return語句只能返回單個的值,解決辦法是將要返回的值都包含在一個根對象中。
2⃣️JSX不能使用if語句,可使用三元表達式替代,或者將條件語句移動到JSX外部。
<script type="text/babel"> //初始化動態數據 var title = 'I Love you!'; var myName = 'bww'; //創建虛擬dom : JSX var vDOM = <h1 id="myTitle" name={myName}>{title}</h1>; //將虛擬dom渲染中頁面元素中 ReactDOM.render(vDOM, document.getElementById('example1')); </script>
8. 自定義組件(Component) :
1). 定義組件
//方式1: 工廠(無狀態)函數(最簡潔, 推薦使用)
function MyComponent1() {
return <h1>自定義組件標題11111</h1>
}
//方式2: ES6類語法(複雜組件, 推薦使用)
class MyComponent3 extends React.Component {
render () {
return <h1>自定義組件標題33333</h1>
}
}
//方式3: ES5老語法(不推薦使用了)
var MyComponent2 = React.createClass({
render () {
return <h1>自定義組件標題22222</h1>
}
})
2). 渲染組件標簽
ReactDOM.render(<MyComponent/>, document.getElementById('example'));
註意:
1). 返回的組件類必須首字母大寫
2). 虛擬DOM元素必須只有一個根元素
3). 虛擬DOM元素必須有結束標簽
ReactDOM.render()渲染組件標簽的基本流程
1). React內部會創建組件實例對象
2). 得到包含的虛擬DOM並解析為真實DOM
3). 插入到指定的頁面元素內部
9.組件實例對象3大屬性之一: props屬性
1. 每個組件對象都會有props(properties的簡寫)屬性
2. 組件標簽的所有屬性都保存在props中
3. 內部讀取某個屬性值: this.props.propertyName
4. 作用: 通過標簽屬性從組件外向組件內傳遞數據(只讀)
5. 對props中的屬性值進行類型限制和必要性限制
Person.propTypes = {
name: React.PropTypes.string.isRequired,
age: React.PropTypes.number.isRequired
}
6. 擴展屬性: 將對象的所有屬性通過props傳遞
<Person {...person}/>
7. 預設屬性值
Person.defaultProps = {
name: 'Mary'
};
8. 組件類的構造函數
constructor (props) {
super(props);
console.log(props); // 查看所有屬性
}
//缺失時設置預設屬性 Person.defaultProps = { sex: '男', age: 18 }; //初始化數據 let person = {name: 'atguigu', sex: '女', age: 3}; //根據數據動態渲染組件標簽 /*ReactDOM.render(<Person name={person.name} age= {person.age} sex={person.sex}/>, document.getElementById('example'));*/ ReactDOM.render(<Person {...person}/>, document.getElementById('example')); const person2 = {name: 'kobe', sex: '女'}; ReactDOM.render(<Person {...person2}/>, document.getElementById('example2'));
1 <script type="text/babel"> 2 //定義內部標題組件 3 class Welcome extends React.Component { 4 render() { 5 return <h2>Welcome {this.props.name}!</h2>; 6 } 7 } 8 Welcome.propTypes = { 9 name: React.PropTypes.string.isRequired 10 }; 11 //定義外部應用組件 12 class App extends React.Component { 13 render() { 14 return ( 15 <div> 16 { 17 this.props.names.map( 18 (name, index) => <Welcome name={name} key={index}/> 19 ) 20 } 21 </div> 22 ); 23 } 24 } 25 App.propTypes = { 26 names: React.PropTypes.array.isRequired 27 }; 28 29 /**********************************************************/ 30 31 var names = ['Tom', 'Jack', "Bob"]; 32 ReactDOM.render(<App names={names}/>, document.getElementById('example')); 33 </script>View Code
10. 組件實例對象的3大屬性之二: refs屬性
1). 組件內的標簽都可以定義ref屬性來標識自己
2). 在組件中可以通過this.refs.refName來得到對應的真實DOM對象
3). 作用: 用於操作指定的ref屬性的dom元素對象(表單標簽居多)
* <input ref='username' />
* this.refs.username //返回input對象
事件處理
1). 通過onXxx屬性指定組件的事件處理函數(註意大小寫)
* React使用的是自定義(合成)事件, 而不是使用的DOM事件
* React中的事件是通過委托方式處理的(委托給組件最外層的元素)
2). 通過event.target得到發生事件的DOM元素對象
<input onFocus={this.handleClick}/>
handleFocus(event) {
event.target //返回input對象
}
強烈註意
1). 組件內置的方法中的this為組件對象
2). 在組件中自定義的方法中的this為null
* 強制綁定this
* 箭頭函數(ES6模塊化編碼時才能使用)
1 class RefsTest extends React.Component { 2 constructor (props) { 3 super(props); 4 5 this.showMsg = this.showMsg.bind(this); // 強制給showMsg()綁定this(組件對象) 6 this.handleBlur = this.handleBlur.bind(this); 7 } 8 9 showMsg() { 10 // console.log(this); //this預設是null, 而不組件對象 11 const input = this.refs.msg; 12 alert(input.value); 13 } 14 15 handleBlur(event) { 16 const input = event.target; 17 alert(input.value); 18 } 19 20 render () { 21 return ( 22 <div> 23 <input type="text" ref="msg"/> 24 <button onClick={this.showMsg}>提示輸入數據</button> 25 <input type="text" placeholder="失去焦點提示數據" onBlur={this.handleBlur}/> 26 </div> 27 ); 28 } 29 }View Code
11.組件實例對象3大屬性之: state屬性
1). 組件被稱為"狀態機", 通過更新組件的狀態值來更新對應的頁面顯示(重新渲染)
2). 初始化狀態:
constructor (props) {
super(props)
this.state = {
stateProp1 : value1,
stateProp2 : value2
}
}
3). 讀取某個狀態值
this.state.statePropertyName
4). 更新狀態---->組件界面更新
this.setState({
stateProp1 : value1,
stateProp2 : value2
})
12.受控組件
class TwoWay extends React.Component { constructor(props) { super(props) this.state = { msg: 'atguigu' } this.handleChange = this.handleChange.bind(this) } handleChange(event) { let msg = event.target.value this.setState({msg}) } render() { return ( <div> <input type="text" value={this.state.msg} onChange={this.handleChange}/> <p>{this.state.msg}</p> </div> ) } }