1. 概述
React 是一個(gè)用于構(gòu)建用戶界面的 JAVASCRIPT 庫(kù)洗鸵。
React 主要用于構(gòu)建 UI沛膳,很多人認(rèn)為 React 是 MVC 中的 V(視圖)扛施。
React 起源于 Facebook 的內(nèi)部項(xiàng)目漓穿,用來(lái)架設(shè) Instagram 的網(wǎng)站枷餐,并于 2013 年 5 月開(kāi)源坷衍。
React 擁有較高的性能寝优,代碼邏輯非常簡(jiǎn)單,越來(lái)越多的人已開(kāi)始關(guān)注和使用它枫耳。
1.1 React 特點(diǎn)
- 1.聲明式設(shè)計(jì) ?React采用聲明范式乏矾,可以輕松描述應(yīng)用。
- 2.高效 ?React通過(guò)對(duì)DOM的模擬迁杨,最大限度地減少與DOM的交互钻心。
- 3.靈活 ?React可以與已知的庫(kù)或框架很好地配合。
- 4.JSX ? JSX 是 JavaScript 語(yǔ)法的擴(kuò)展仑最。React 開(kāi)發(fā)不一定使用 JSX 扔役,但我們建議使用它。
- 5.組件 ? 通過(guò) React 構(gòu)建組件警医,使得代碼更加容易得到復(fù)用亿胸,能夠很好的應(yīng)用在大項(xiàng)目的開(kāi)發(fā)中。
- 6.單向響應(yīng)的數(shù)據(jù)流 ? React 實(shí)現(xiàn)了單向響應(yīng)的數(shù)據(jù)流预皇,從而減少了重復(fù)代碼侈玄,這也是它為什么比傳統(tǒng)數(shù)據(jù)綁定更簡(jiǎn)單。
1.2 安裝
- 使用 create-react-app 快速構(gòu)建 React 開(kāi)發(fā)環(huán)境
(create-react-app 自動(dòng)創(chuàng)建的項(xiàng)目是基于 Webpack + ES6 )
執(zhí)行以下命令創(chuàng)建項(xià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好處
- 更容易編寫(xiě)React組件吟温,因?yàn)榭梢允褂肏TML標(biāo)簽來(lái)描述組件的結(jié)構(gòu)和樣式序仙。
- 可以添加注釋,使代碼更易于理解和維護(hù)鲁豪。
- 可以在JavaScript代碼中直接操作DOM元素潘悼,而不需要通過(guò)瀏覽器渲染頁(yè)面律秃。
JSX會(huì)被翻譯成JS,只是JS的語(yǔ)法糖
2.4 虛擬DOM與真實(shí)DOM
虛擬DOM
- 本質(zhì)是Object類型的一般對(duì)象
- 虛擬DOM比較輕治唤,真實(shí)DOM比較重
- 虛擬DOM最終會(huì)被React轉(zhuǎn)化為真實(shí)DOM棒动,呈現(xiàn)在頁(yè)面上
3. JSX語(yǔ)法規(guī)則
- 定義虛擬DOM時(shí),不要寫(xiě)引號(hào)
const VDOM = <h1> Hello React</h1>
const VDOM = "<h1> Hello React</h1>" //加引號(hào)變成字符串
- 標(biāo)簽中混入JS表達(dá)式 [會(huì)產(chǎn)生一個(gè)存在或不存在的值] 時(shí)要用
{ }
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 }}的形式去寫(xiě)
const VDOM = (
<h1 style = {{color:'white',fontSize:'29px'}}>
<span>hello</span>
</h1>
)
- 只能有一個(gè)根標(biāo)簽
const VDOM =(
<div>
<div></div>
<div></div>
</div>
)
//多個(gè)根標(biāo)簽報(bào)錯(cuò)
const VDOM =(
<div></div>
<div></div>
)
- 所有標(biāo)簽必須閉合
const VDOM = (
<input type="text"></input>
)
const VDOM = (
<input type="text" />
)
- 標(biāo)簽首字母
- 若小寫(xiě)字母開(kāi)頭船惨,則將標(biāo)簽轉(zhuǎn)為html中同名元素,html中無(wú)對(duì)應(yīng)元素報(bào)錯(cuò)
- 若大寫(xiě)字母開(kāi)頭缕陕,react就把該標(biāo)簽渲染為組件粱锐,組件未定義則報(bào)錯(cuò)
//會(huì)被識(shí)別為組件
const VDOM = (
<Hello></Hello>
)
//會(huì)被識(shí)別為html標(biāo)簽,找不到對(duì)應(yīng)標(biāo)簽報(bào)錯(cuò)
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ù)式組件
- 適用于簡(jiǎn)單組件的定義
<div id="test"></div>
<script type = 'text/babel'>
<!-- 創(chuàng)建函數(shù)式組件 -->
function MyComponent(){
return <h2>我是用函數(shù)定義的組件</h2>
}
//渲染組件到頁(yè)面,注意首字母大寫(xiě)扛邑,小寫(xiě)會(huì)被當(dāng)做html標(biāo)簽
ReactDOM.render(<MyComponent/>,document.getElementById("test"))
</script>
4.2 類式組件
類
- 類中的構(gòu)造器不是必須寫(xiě)的怜浅,要對(duì)實(shí)例進(jìn)行一些初始化的操作,如添加指定屬性時(shí)才寫(xiě)
- 如果A類繼承了B類鹿榜,且A類中寫(xiě)了構(gòu)造器海雪,那么A類構(gòu)造器中的super是必須要調(diào)用的
- 類中所定義的方法,都是放在了類的原型對(duì)象上舱殿。供實(shí)例去使用
<script type = 'text/javascript'>
//創(chuàng)建一個(gè)Person類
class Person {
//構(gòu)造器方法
constructor(name, age) {
console.log(this);//構(gòu)造器中的this是奥裸,類的實(shí)例對(duì)象(new是誰(shuí)就是誰(shuí))
this.name = name
this.age = age
}
//一般方法
speak() {
//spack方法放在了哪里?--類的原型對(duì)象上沪袭,供實(shí)例使用
console.log(this);
//通過(guò)Person實(shí)例調(diào)用speak時(shí)湾宙,speak中的this就是Person實(shí)例
console.log(`我叫${this.name},我的年齡是${this.age}`)
}
}
// 創(chuàng)建一個(gè)Person的實(shí)例對(duì)象
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
}
//重寫(xiě)從父類繼承過(guò)來(lái)的方法
speak() {
console.log(`我叫${this.name},我的年齡是${this.age},我的班級(jí)是${this.grade}`)
}
//一般方法
study() {
//study方法放在了哪里冈绊?類的原型對(duì)象上侠鳄,供實(shí)例使用
console.log("我愛(ài)學(xué)習(xí)")
}
}
const s1 = new Student('tina', 20,'5年級(jí)')
console.log(s1);
s1.speak()
類式組件(簡(jiǎn)單)
- 必須繼承
React.Component
- 必須有render,且render必須有返回值
<script type = 'text/javascript'>
//1.創(chuàng)建類式組件
class MyComponent extends React.Component{
//render放在哪死宣?--MyComponent的原型對(duì)象上伟恶,供實(shí)例使用
//render中的this是誰(shuí)?--MyComponent的實(shí)例對(duì)象
render(){
return <h2>我是類定義的組件</h2>
}
}
//2.渲染組件到頁(yè)面
ReactDOM.render(<MyComponent/>,document.getElementById("test")
// 執(zhí)行了ReactDOM.render(<MyComponent/>,document.getElementById("test")后
// 1.React解析組件標(biāo)簽毅该,找到了Mycomponent組件
// 2.發(fā)現(xiàn)組件是使用類定義的博秫,隨后new出來(lái)該類的實(shí)例,并通過(guò)該實(shí)例調(diào)用到原型上的render方法
// 3.將render返回的虛擬DOM轉(zhuǎn)為真實(shí)DOM眶掌,隨后呈現(xiàn)到頁(yè)面中
</script>
5. state
- state最好寫(xiě)成對(duì)象
<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.渲染組件到頁(yè)面
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被點(diǎn)擊')
})
const btn2 = document.getElementById('btn2')
btn2.onclick = ()=>{
alert('按鈕2被點(diǎn)擊')
}
function demo(){
alert('按鈕3被點(diǎn)擊')
}
</script>
react事件綁定
- 把原生的
onclick
換成onClick
- 方法外不能加引號(hào)
- 方法不能加括號(hào)
<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.渲染組件到頁(yè)面
ReactDOM.render(<MyComponent/>,document.getElementById("test")
function demo(){
console.log('標(biāo)題被點(diǎn)擊')
}
</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.渲染組件到頁(yè)面
ReactDOM.render(<MyComponent/>,document.getElementById("test")
</script>