react 有手機 app 擴展庫 --ReactNative 使用原生 JS 開發(fā)手機 app
React 開發(fā)分兩種方式 1.腳本方式 2.腳手架方式
腳本方式
- 引入 react.js腳本
- React提供兩個類
React:負責創(chuàng)建元素
ReactDOM:負責渲染元素鞋吉,其他的元素中 - 利用 React 創(chuàng)建元素
例:let h3 = React.createElement( "h3" ,{ id:"time", className:"time"}, "當前時間:10:12" )
- 利用 ReactDOM 渲染到"id=root"標簽中
React.render(h3,"root")
學習JSX
- JSX:在 js 中書寫 xml格式的DOM 操作代碼暑认; html 是 xml 中的一種荷憋,即標簽語言
- JSX屬于特殊語法淑掌,瀏覽器不認識豁遭,瀏覽器無法識別贱鄙,因此需要 引入babel 工具進行翻譯而晒,并且在 script 標簽上加 type="text/babel",代表此腳本必須 使用babel 編譯
- 例:
// 把當前時間展示到 id="root" 的標簽中
let tiem = "10:56"
let h3 = <h3 className="danger" id="time">當前時間:{ time }<h3>
ReactDOM.render(h3,root);
注意:vue搪桂,angular略步,小程序中差值表達式為 {{ js 代碼 }}描扯,而 JSX 中為 { js 代碼 }
學習組件
- 組件:組成頁面的零件
- 組件的特征:復用性
- React 采用 函數(shù) 和 類 制作組件
1)函數(shù):適合簡單組件制作
2) 類:適合復雜組件制作 - 組件函數(shù)名要求大坨峰寫法:更容易區(qū)分組件和普通函數(shù)
- 例:
函數(shù)方式
function HelloWord () {
return <h1>hello word!</h1>;
};
ReactDOM.render(HelloWord (),root);
// 語法糖寫法,babel自動編譯成 HelloWord()
ReactDOM.render(<HelloWord/>,root);
// render() :非新增操作而是會覆蓋
// 復用性:
let more = (<div>
<HelloWord/>
<HelloWord/>
<HelloWord/>
</div>)
ReactDOM.render(more,root);
類方式
1)類方式制作組件:創(chuàng)建具有強大能力的組件要求必須繼承父類
class HelloWord extends React.component {
render(){
return <h1>Hello Word!</h1>
}
}
// 使用
React.render(new HelloWord().render(),root);
// 語法糖寫法
React.render(<HelloWord/>,root);
// 復用行
let more = (<div>
<HelloWord/>
<HelloWord/>
<HelloWord/>
</div>)
React.render(more,root);
父子傳參
1)函數(shù)組件傳參
function HelloWord (props) {
return <h1>hello,{props.name}</h1>
};
React.render(HelloWord( {name:"中國"} ),root)趟薄;
// 語法糖
React.render(<HelloWord name="中國"/>,root)绽诚;
2)類組件傳參
this.props 來自于父類的constructor 方法,該方法 new 時自動觸發(fā)
class HelloStar extends React.component {
// 帶有 this 前綴說明props 是成員屬性杭煎,成員屬性可以跨方法使用
// constructor(props) {
// this.props = props;
// }
render() {
return <h1>hello,{this.props.star}</h1>
}
}
ReactDOM.render(new HelloStar({name:"林俊杰"}),render(),root);
// 語法糖
ReactDOM.render(<HelloStar name="林俊杰"/>,root);
事件
- 用戶可以通過操作 UI觸發(fā)各種事件恩够,如點擊事件、失焦事件等
- 函數(shù)書寫建議使用箭頭函數(shù)不會出現(xiàn) this 指向問題
class Demo extends React.component {
name = "俊杰"
show = () =>{
console.log(this.name)
}
render() {
// 事件的綁定
// vue 中 v-on:click="方法名"羡铲,簡寫@click="方法名"
// React 中 onClick="方法名"
// React 中 {}中的方法會直接執(zhí)行 蜂桶,所以方法是否加()是有區(qū)別的,加會直接執(zhí)行,不加事件觸發(fā)執(zhí)行
return (
<div>
<button onClick={this.show}>點擊觸發(fā)~</button>
<button onClick={this.show()}>點擊觸發(fā)~</button>
</div>
)
}
}
狀態(tài)值
- React中植阴,使用state存儲數(shù)據(jù),通過{ }顯示在頁面上处坪,利用 setState( )更新數(shù)據(jù)疆股,可以讓 UI 同步刷新
- state狀態(tài)值只有使用類組件才能使用
- vue 中只要修改數(shù)據(jù)頁面就會更新费坊,React 中必須使用 state 和 setState 配合
- state 中的數(shù)據(jù)必須使用 setState 頁面才會刷新頁面,setState 會做兩件事 修改數(shù)據(jù)+修改 UI
class Demo extends React.component {
state = {
count:1
}
_addCount = ()=>{
// setState是異步操作押桃,方法第二個參數(shù)是回調(diào)函數(shù)葵萎,在數(shù)據(jù)渲染成功時觸發(fā)
this.setState({count:this.state.count + 1},()=>{
console.log("回調(diào)函數(shù)",this.state.count);
})
}
// 類中的方法有很多唱凯,通常分為兩種
// 1)事件綁定 2)普通方法
// 約定與事件綁定的方法帶前綴 _
render(){
return (
<div>
<h3>{this.state.count}</h3>
<butten onClick={this._addCount}>點擊+1</butten>
</div>
)
}
}
ReactDOM.render(<Demo/>,root);
安裝腳手架
- 腳手架是一個工具羡忘,可以快速搭建項目的基本架構(gòu)完成所需資源的下載和配置
- 腳手架安裝要求 node >=8.10 &&npm >= 5.6 查看當前版本 node -v && npm -v
- React 腳手架安裝命令: npm i -g create-react-app,創(chuàng)建項目命令: create-react-app 項目名
- 創(chuàng)建的項目名不允許有大寫字母
-
安裝官方插件磕昼,rcc 生成項目基本結(jié)構(gòu)卷雕,vscode 不識別 JSX 語言,切換語言為JavaScript React才會有代碼提示
image.png - 項目的啟動流程
1)項目下執(zhí)行 npm start 命令會開啟一個服務(wù)器票从,服務(wù)器程序唯一標識 端口號:3000
2)瀏覽器上訪問localhost:3000
3)webpack工具:腳手架自動配置了此工具漫雕,項目運行時會自動打包index.js引入到 index.html 中
4)index.js 引入了 App.js并且渲染到 id="root" 的標簽上
5)App.js 項目的根組件 - React項目是 SPA 項目:Single web Page Application,即單網(wǎng)頁應用,只有一個頁面峰鄙,通過路由切換局部內(nèi)容浸间,實現(xiàn)頁面變更
條件渲染
- React 的條件渲染不同于 Vue ,需要單獨寫一個函數(shù)并在渲染出調(diào)用
- 為什么調(diào)用時 沒有 this 指向問題吟榴?此方法不是事件觸發(fā)而是刷新時觸發(fā)魁蒜,this 指向不是 window
- 判斷條件一定是 state相關(guān)的值,setState 更新時就會自動刷新更新 UI
show() {
if(this.state.num == 0) return <h1>000</h1>
if(this.state.num == 1) return <h1>111</h1>
}
render() {
return (
<div>當前號碼</div>
{this.show()}
)
}
列表渲染
- React 中的列表渲染需要單獨寫一個方法去改造數(shù)組吩翻,實現(xiàn)數(shù)組里放 JSX 語法渲染
- 循環(huán)數(shù)組的每項都需要帶一個唯一標識 key
- 使用數(shù)組的 map 方法會更簡單的實現(xiàn)列表渲染
arr = [11,22,33,44]
arrFn () {
let arr2 = [];
this.arr.forEach((item,index) =>{
arr2.push(<div key={index}>{item}</div>)
});
return arr2;
}
// 使用數(shù)組的 map 方法
arrMapFn () {
return this.arr.map((item,index)=>{
return <div key={index}>{item}</div>
}
)
}
render () {
return (
<div>{this.arrFn()}</div>
)
}
動態(tài)風格樣式
- 即在頁面展示時 樣式能動態(tài)的發(fā)生變化
- JSX語法中樣式需要寫成對象類型
- 樣式分為兩種寫法___ 1)內(nèi)聯(lián)式 style ___2)外部樣式 css文件+class
1)內(nèi)聯(lián)式
//點擊按鈕使文字變大
state={
size:18
}
render() {
return (
<div style={{fontSize: this.state.size + "px"}}>Hello</div>
<button onClick={() => this.setState({size : this.state.size + 2})}>點擊變大</button>
)
}
2)外部樣式
// App.css
.style1 {
background-color: #fff;
}
.style2 {
background-color: #000;
}
.style3 {
background-color: #999;
}
// App.js
import "./App.css";
state={ size:18 }
styleFn() {
let num = this.state.size;
if(num == 20) return "style1"
if(num == 22) return "style2"
if(num == 24) return "style3"
}
render () {
return (
<div className={this.styleFn()}>hello</div>
<button onClick={() => this.setState({size : this.state.size + 2})}>點擊變大</button>
)
}
雙向數(shù)據(jù)綁定
- from表單中的元素兜看,通常能夠與用戶交互,此時會出現(xiàn)數(shù)據(jù)綁定到 UI 元素狭瞎,UI 元素因為用戶操作發(fā)生變化细移,同步更新到數(shù)據(jù)的情況,即為雙向數(shù)據(jù)綁定
- 用戶更改 UI 會觸發(fā) onChange方法熊锭,使用 onChange方法實現(xiàn)UI 變化時數(shù)據(jù)同步
- 事件觸發(fā)的方法弧轧,會帶 event 事件對象參數(shù)
- 事件默認是 Dom 事件,但在 React 中對 Dom 事件進行了處理碗殷,處理之后的事件叫做 同步事件
- 同步事件:把值傳入后會自動銷毀自身劣针,要想打印事件中的值必須調(diào)用event.persist(),對讀值沒有影響,且不是實時的值
state={
uname: "",
upwd: ""
}
_changeN=(event)=>{
// event.persist()
// console.log(event)
this.setState({uname:event.target.value})
}
_changeP=(event)=>{
// event.persist()
// console.log(event)
this.setState({upwd:event.target.value})
}
render(){
return (
<input/ type="text" placeholder="用戶名" value={this.state.uname} onChange={this._changeN}>
<input/ type="password" placeholder="密碼" onChange={this._changeP}>
<button>登錄</button>
)
}
生命周期
- 組件生成亿扁、更新、銷毀的過程
- 組件的每個關(guān)鍵過程都會有鉤子函數(shù)被觸發(fā)
- componentDidMount鉤子函數(shù)會在被掛載時觸發(fā)鸟廓,通常在這個鉤子函數(shù)中發(fā)送請求从祝,獲取數(shù)據(jù)
- componentWillUnmount鉤子函數(shù)會在組件被銷毀時觸發(fā)襟己,通常在這個鉤子函數(shù)中銷毀一些資源防止內(nèi)存泄漏,例如定時器
- componentDidUpdate鉤子函數(shù)會在組件更新時觸發(fā)牍陌,有兩個參數(shù)props擎浴,state
1)props:屬性,接收外來傳參,props是舊值毒涧,新值是 this.props
2)state:狀態(tài)值贮预,組件本身的變化,state 是舊值契讲,新值是 this.state - shouldComponentUpdate鉤子函數(shù)的兩個參數(shù)會返回即將變化的值仿吞,以此來判斷是否更新組件,提高 React 的渲染效率捡偏,面試會經(jīng)常問
import React, { Component } from 'react'
export default class App extends Component {
state = {
show: false
}
isShow() {
if(this.state.show) return <Son/>
}
render() {
return (
<div>
{this.isShow()}
<button onClick={()=>this.setState({show:!this.state.show})}>點擊</button>
</div>
)
}
}
class Son extends Component {
componentDidMount() {
console.log('componentDidMount鉤子函數(shù)觸發(fā),組件掛載');
};
componentWillUnmount() {
console.log('componentWillUnmount鉤子函數(shù)觸發(fā),組件銷毀');
};
componentDidUpdate(props,state) {
console.log('舊值', props, '新值', this.props)
console.log('舊值',state,'新值',this.state)
};
shouldComponentUpdate(props, state) {
// props,state 代表即將變化的值,即即將展示的值
if (state.count % 2) {
// false 代表組件不會刷新到頁面上唤冈,則 didupdate 函數(shù)也不會觸發(fā)
return false
} else {
return true
};
};
render() {
return (
<div>我是子組件</div>
)
}
}