1. 概述
React 是一個用于構(gòu)建用戶界面的 JAVASCRIPT 庫。
React 主要用于構(gòu)建 UI,很多人認(rèn)為 React 是 MVC 中的 V(視圖)。
React 起源于 Facebook 的內(nèi)部項目,用來架設(shè) Instagram 的網(wǎng)站,并于 2013 年 5 月開源。
React 擁有較高的性能,代碼邏輯非常簡單,越來越多的人已開始關(guān)注和使用它。
1.1 React 特點
- 1.聲明式設(shè)計 ?React采用聲明范式,可以輕松描述應(yīng)用。
- 2.高效 ?React通過對DOM的模擬,最大限度地減少與DOM的交互。
- 3.靈活 ?React可以與已知的庫或框架很好地配合。
- 4.JSX ? JSX 是 JavaScript 語法的擴展。React 開發(fā)不一定使用 JSX ,但我們建議使用它。
- 5.組件 ? 通過 React 構(gòu)建組件,使得代碼更加容易得到復(fù)用,能夠很好的應(yīng)用在大項目的開發(fā)中。
- 6.單向響應(yīng)的數(shù)據(jù)流 ? React 實現(xiàn)了單向響應(yīng)的數(shù)據(jù)流,從而減少了重復(fù)代碼,這也是它為什么比傳統(tǒng)數(shù)據(jù)綁定更簡單。
1.2 安裝
- 使用 create-react-app 快速構(gòu)建 React 開發(fā)環(huán)境
(create-react-app 自動創(chuàng)建的項目是基于 Webpack + ES6 )
執(zhí)行以下命令創(chuàng)建項目:
$ cnpm install -g create-react-app
$ create-react-app my-app
$ cd my-app/
$ npm start
2. 創(chuàng)建虛擬DOM的兩種方式
2.1 JSX創(chuàng)建虛擬DOM
<body>
<div id="text"></div>
<script type="text/babel">
const VDOM = <h1> Hello React</h1>
ReactDom.render(VDOM,document.getElementById('test'))
</script>
</body>
2.2 JS創(chuàng)建虛擬DOM
<body>
<div id="text"></div>
<script type="text/babel">
const VDOM = React.createElement('h1',{id:'title'},'Hello React')
ReactDom.render(VDOM,document.getElementById('test'))
</script>
</body>
2.3 JSX好處
- 更容易編寫React組件,因為可以使用HTML標(biāo)簽來描述組件的結(jié)構(gòu)和樣式。
- 可以添加注釋,使代碼更易于理解和維護。
- 可以在JavaScript代碼中直接操作DOM元素,而不需要通過瀏覽器渲染頁面。
JSX會被翻譯成JS,只是JS的語法糖
2.4 虛擬DOM與真實DOM
虛擬DOM
- 本質(zhì)是Object類型的一般對象
- 虛擬DOM比較輕,真實DOM比較重
- 虛擬DOM最終會被React轉(zhuǎn)化為真實DOM,呈現(xiàn)在頁面上
3. JSX語法規(guī)則
- 定義虛擬DOM時,不要寫引號
const VDOM = <h1> Hello React</h1>
const VDOM = "<h1> Hello React</h1>" //加引號變成字符串
- 標(biāo)簽中混入JS表達式 [會產(chǎn)生一個存在或不存在的值] 時要用
{ }
const myId = 'TITle'
const myData = 'Hello React'
const VDOM = (
<h1 id={myId.toLowerCase()}>
<span>{myData}</span>
</h1>
)
- 樣式的類名指定不能用class,用className
const VDOM = (
<h1 className="title">
<span>hello</span>
</h1>
)
- 內(nèi)聯(lián)樣式要用style={{ key: value }}的形式去寫
const VDOM = (
<h1 style = {{color:'white',fontSize:'29px'}}>
<span>hello</span>
</h1>
)
- 只能有一個根標(biāo)簽
const VDOM =(
<div>
<div></div>
<div></div>
</div>
)
//多個根標(biāo)簽報錯
const VDOM =(
<div></div>
<div></div>
)
- 所有標(biāo)簽必須閉合
const VDOM = (
<input type="text"></input>
)
const VDOM = (
<input type="text" />
)
- 標(biāo)簽首字母
- 若小寫字母開頭,則將標(biāo)簽轉(zhuǎn)為html中同名元素,html中無對應(yīng)元素報錯
- 若大寫字母開頭,react就把該標(biāo)簽渲染為組件,組件未定義則報錯
//會被識別為組件
const VDOM = (
<Hello></Hello>
)
//會被識別為html標(biāo)簽,找不到對應(yīng)標(biāo)簽報錯
const VDOM = (
<good></good>
)
eg
const data = [1,2,3,4]
const VDOM = {
<div>
<ul>
{
data.map((item,index)=>{
return <li key={index}>{item}</li>
})
}
</ul>
</div>
}
4. 組件與模塊
4.1 函數(shù)式組件
- 適用于簡單組件的定義
<div id="test"></div>
<script type = 'text/babel'>
<!-- 創(chuàng)建函數(shù)式組件 -->
function MyComponent(){
return <h2>我是用函數(shù)定義的組件</h2>
}
//渲染組件到頁面,注意首字母大寫,小寫會被當(dāng)做html標(biāo)簽
ReactDOM.render(<MyComponent/>,document.getElementById("test"))
</script>
4.2 類式組件
類
- 類中的構(gòu)造器不是必須寫的,要對實例進行一些初始化的操作,如添加指定屬性時才寫
- 如果A類繼承了B類,且A類中寫了構(gòu)造器,那么A類構(gòu)造器中的super是必須要調(diào)用的
- 類中所定義的方法,都是放在了類的原型對象上。供實例去使用
<script type = 'text/javascript'>
//創(chuàng)建一個Person類
class Person {
//構(gòu)造器方法
constructor(name, age) {
console.log(this);//構(gòu)造器中的this是,類的實例對象(new是誰就是誰)
this.name = name
this.age = age
}
//一般方法
speak() {
//spack方法放在了哪里?--類的原型對象上,供實例使用
console.log(this);
//通過Person實例調(diào)用speak時,speak中的this就是Person實例
console.log(`我叫${this.name},我的年齡是${this.age}`)
}
}
// 創(chuàng)建一個Person的實例對象
const p1 = new Person('tom', 18)
const p2 = new Person('jack', 19)
p1.speak()
p2.speak()
</script>
繼承
class Student extends Person {
constructor(name, age, grade) {
super(name, age)
this.grade = grade
}
//重寫從父類繼承過來的方法
speak() {
console.log(`我叫${this.name},我的年齡是${this.age},我的班級是${this.grade}`)
}
//一般方法
study() {
//study方法放在了哪里?類的原型對象上,供實例使用
console.log("我愛學(xué)習(xí)")
}
}
const s1 = new Student('tina', 20,'5年級')
console.log(s1);
s1.speak()
類式組件(簡單)
- 必須繼承
React.Component - 必須有render,且render必須有返回值
<script type = 'text/javascript'>
//1.創(chuàng)建類式組件
class MyComponent extends React.Component{
//render放在哪?--MyComponent的原型對象上,供實例使用
//render中的this是誰?--MyComponent的實例對象
render(){
return <h2>我是類定義的組件</h2>
}
}
//2.渲染組件到頁面
ReactDOM.render(<MyComponent/>,document.getElementById("test")
// 執(zhí)行了ReactDOM.render(<MyComponent/>,document.getElementById("test")后
// 1.React解析組件標(biāo)簽,找到了Mycomponent組件
// 2.發(fā)現(xiàn)組件是使用類定義的,隨后new出來該類的實例,并通過該實例調(diào)用到原型上的render方法
// 3.將render返回的虛擬DOM轉(zhuǎn)為真實DOM,隨后呈現(xiàn)到頁面中
</script>
5. state
- state最好寫成對象
<script type = 'text/javascript'>
//1.創(chuàng)建類式組件
class MyComponent extends React.Component{
constructor(props){
super(props)
this.state = {isHot:true}
}
render(){
//讀取state
const {isHot} = this.state
return <h2>今天的天氣很{isHot?'炎熱:涼爽'}</h2>
}
}
//2.渲染組件到頁面
ReactDOM.render(<MyComponent/>,document.getElementById("test")
</script>
6. 事件綁定
原生事件綁定
<button id="btn1"> 按鈕1 </button>
<button id="btn2"> 按鈕2 </button>
<button onclick = "click()"> 按鈕3 </button>
<script type = 'text/javascript'>
const btn1 = document.getElementById('btn1')
btn1.addEventListener('click',()=>{
alert('按鈕1被點擊')
})
const btn2 = document.getElementById('btn2')
btn2.onclick = ()=>{
alert('按鈕2被點擊')
}
function demo(){
alert('按鈕3被點擊')
}
</script>
react事件綁定
- 把原生的
onclick換成onClick - 方法外不能加引號
- 方法不能加括號
<script type = 'text/javascript'>
//1.創(chuàng)建類式組件
class MyComponent extends React.Component{
constructor(props){
super(props)
this.state = {isHot:true}
}
render(){
//讀取state
const {isHot} = this.state
return <h2 onClick={demo}>今天的天氣很{isHot?'炎熱:涼爽'}</h2>
}
}
//2.渲染組件到頁面
ReactDOM.render(<MyComponent/>,document.getElementById("test")
function demo(){
console.log('標(biāo)題被點擊')
}
</script>
1
<script type = 'text/javascript'>
//1.創(chuàng)建類式組件
class Weather extends React.Component{
constructor(props){
super(props)
this.state = {isHot:true}
}
render(){
//讀取state
const {isHot} = this.state
return <h2 onClick={changeWeather}>今天的天氣很{isHot?'炎熱:涼爽'}</h2>
}
changeWeather(){
}
}
//2.渲染組件到頁面
ReactDOM.render(<MyComponent/>,document.getElementById("test")
</script>