React基础学习(第二天)
生活随笔
收集整理的這篇文章主要介紹了
React基础学习(第二天)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
虛擬DOM
- JSX 涉及到 虛擬DOM ,簡單聊一下
定時(shí)器渲染問題
// 方法 function render() {//2. 創(chuàng)建react對象let el = (<div><h3>時(shí)間更新</h3><p>{ new Date().toLocaleTimeString()}</p></div>)//3. 渲染ReactDOM.render(el, document.getElementById('root')) }//4. 開啟一個(gè)定時(shí)器, 每秒渲染一次 setInterval(() => {render() }, 1000)渲染模式 :
/*** 最早的更新模式* 1. 數(shù)據(jù)* 2. 模板* 3. 數(shù)據(jù)+模板 => 真實(shí)的DOM* 4. 數(shù)據(jù)變了 => 最簡單直接的方式 => 最新數(shù)據(jù)+模板 => 新的DOM* 5. 新的DOM 把 舊的DOM完全直接替換掉* 6. 顯示新的DOM** 缺點(diǎn) : 完全替換, 性能不好** 1. 數(shù)據(jù)* 2. 模板* 3. 數(shù)據(jù)+模板 => 真實(shí)的DOM* 4. 數(shù)據(jù)變化了 => 最新的數(shù)據(jù) + 模板 => 新的DOM* 5. 新的DOM 和 舊的DOM 進(jìn)行一一比較, 找到需要更新的地方* 6. 只需要更新需要改變的地方即可** 優(yōu)點(diǎn) : 不再是全部替換掉,* 缺點(diǎn) : DOM比較就有性能問題了 , 會有多余的DOM和屬性進(jìn)行比較(打印一級屬性),有損性能* p 和 p對比 h3 和h3對比(多余的對比)** 1. 數(shù)據(jù)* 2. 模板* 3. 數(shù)據(jù) + 模板 => 虛擬DOM (js對象) => 真實(shí)的DOM* 4. 數(shù)據(jù)發(fā)生改變(zs=>ls) => 最新的數(shù)據(jù) + 模板 => 新的虛擬DOM* 5. 新的虛擬DOM 和 舊的虛擬DOM 通過 diff算法 進(jìn)行比較* 6. 找到有差異的地方,(需要更新的地方)* 7. 更新一下就可以看到最新的DOM了*/- 打印屬性 :
- 查看圖片 : 演示對比找差異渲染
- 文字描述 :
DIff 算法
React 中有兩種假定:
- 1 兩個(gè)不同類型的元素會產(chǎn)生不同的樹
- 2 開發(fā)者可以通過 key 屬性指定不同樹中沒有發(fā)生改變的子元素
Diff 算法的說明 - 1
- 如果兩棵樹的根元素類型不同,React 會銷毀舊樹,創(chuàng)建新樹
Diff 算法的說明 - 2
- 對于類型相同的 React DOM 元素,React 會對比兩者的屬性是否相同,只更新不同的屬性
- 當(dāng)處理完這個(gè) DOM 節(jié)點(diǎn),React 就會遞歸處理子節(jié)點(diǎn)。
Diff 算法的說明 - 3
- 1 當(dāng)在子節(jié)點(diǎn)的后面添加一個(gè)節(jié)點(diǎn),這時(shí)候兩棵樹的轉(zhuǎn)化工作執(zhí)行的很好
- 2 但是如果你在開始位置插入一個(gè)元素,那么問題就來了:
key 屬性
為了解決以上問題,React 提供了一個(gè) key 屬性。當(dāng)子節(jié)點(diǎn)帶有 key 屬性,React 會通過 key 來匹配原始樹和后來的樹。
// 舊 <ul><li key="1">1</li><li key="2">2</li> </ul>// 新 <ul><li key="3">3</li><li key="1">1</li><li key="2">2</li> </ul>執(zhí)行過程:現(xiàn)在 React 知道帶有key '3' 的元素是新的,對于 '1' 和 '2' 僅僅移動位置即可補(bǔ)充說明:
-
key 屬性在 React 內(nèi)部使用,但不會傳遞給你的組件
-
推薦:在遍歷數(shù)據(jù)時(shí),推薦在組件中使用 key 屬性:<li key={item.id}>{item.name}</li>
-
注意:key 只需要保持與他的兄弟節(jié)點(diǎn)唯一即可,不需要全局唯一
-
注意:盡可能的減少數(shù)組 index 作為 key,數(shù)組中插入元素的等操作時(shí),會使得效率底下 。 如果數(shù)組比較簡單, 開發(fā)中沒有刪除和移動操作,使用 index 也是可以的
組件
組件1 - 函數(shù)組件
基本使用
- 函數(shù)組件 : 使用函數(shù)創(chuàng)建的組件叫組函數(shù)組件
- 約定:
- 約定1 : 組件名稱必須是大寫字母開頭, 也就是函數(shù)名稱需要首字母大寫
- 約定2 : 函數(shù)組件必須有返回值
- 不渲染內(nèi)容 : return null
- 渲染內(nèi)容 : return JSX
- 約定3 : 只能有一個(gè)唯一的根元素
- 約定4 : 結(jié)構(gòu)復(fù)雜, 使用() 包裹起來
- 使用 : 把 組件名 當(dāng)成 標(biāo)簽名 一樣使用
傳參
- 傳參 :
- 接收 :
- 函數(shù)的參數(shù)接收 props
- funciton Hello (props) { ... }
- 讀取 : { props.name } 、 { props.age }
- 注意 :
- 傳過來的props 不能添加屬性
- 傳過來的props 不能修改屬性值
- 也可以直接解構(gòu) props里的屬性
- funciton Hello ({ name, age }) { ... }
- 函數(shù)的參數(shù)接收 props
箭頭函數(shù)改造
const Child = () => (<div><div>這是一個(gè)div</div><div>這是一個(gè)div</div></div> )const Hello = ()=> <div>這是哈哈的啊</div>組件2 - 類組件
基本使用
- 類組件 : 使用 ES6 中class 創(chuàng)建的組件, 叫類組件
- 約定 (同 函數(shù)組件)
- 其他約定1 : 類組件必須繼承自 React.Component 父類 , 然后,才可以使用父類中提供的屬性或方法
- 其他約定2 : 必須提供 render 方法, 來指定要渲染的內(nèi)容, render 方法必須有返回值
傳參
- 傳參 : 同函數(shù)組件一樣
- 接收參數(shù)
ES6 - class
介紹
* 類* es6 之前 創(chuàng)建對象 都是通過構(gòu)造函數(shù) 實(shí)現(xiàn)的, 給原型添加方法, 給實(shí)例添加屬性* es6 之后, 給我們提供了一個(gè)字段 class * 通過class 創(chuàng)建對象 * class : 類 * - 類 : 一類對象, 對象的抽象 , 我們可以通過類創(chuàng)建對象* - 動物 人 * * - 對象: 具體的事物, 它有特征(屬性)和行為(方法)* - 狗/貓/鳥 張三/王春春*/使用 class 創(chuàng)建對象
- 使用class 創(chuàng)建一個(gè)類 class Person { }
- 創(chuàng)建對象 let p = new Person()
- 添加屬性 在類里面的 constructor() { } 的里面添加屬性
- 添加方法 直接在類里面添加方法
繼承
- 繼承 : 之前混入, 原型繼承… 都是對象繼承… (對象與對象之間,只要拿過來用就是繼承)
- class 繼承 : 是 類與類之間的繼承 extends
函數(shù)組件和類組件的小結(jié)
- 函數(shù)組件 : 函數(shù)創(chuàng)建組件
- 函數(shù)名首字母一定要大寫
- 把組件當(dāng)成標(biāo)簽使用
- 函數(shù)內(nèi)部 通過 return jsx
- 類組件 : 類創(chuàng)建組件
- 首字母也要大寫
- 一定要繼承(extends) React.Component
- 類里面一定要有一個(gè) render 函數(shù)
- render 函數(shù)里面通過 return jsx
- 類組件也是當(dāng)成標(biāo)簽一樣使用的
函數(shù)組件和類組件的區(qū)別?
- 函數(shù)組件 : 沒有狀態(tài)的, 沒有自己的數(shù)據(jù)
- 類組件 : 有狀態(tài) , 有自己的數(shù)據(jù)
狀態(tài) State 的簡單說明
state 的定義
- 方式1 : constructor 里面
- 方法2 : 屬性初始化語法
獲取 狀態(tài) 值 :
// 直接獲取<p> { this.state.name }</p>// 解構(gòu)獲取const { name } = this.state<p> { name }</p>修改 狀態(tài) 值
// 鉤子函數(shù) - 組件掛載完全 render調(diào)用完后會調(diào)用 componentDidMount() {//1. 直接修改// 如果使用 this.state.name = '春春' , 這樣只會修改state里面的數(shù)據(jù),但是無法更新視圖// this.state.name = '春春'//2. 使用 setState 修改// 1-修改數(shù)據(jù) 2-重新調(diào)用render, 更新視圖this.setState({name: '春春'}) }安裝 React 插件 ==> 查看 state 的值
- react-developer-tools.crx
- 安裝步驟 : 后綴crx 改為 zip, 解壓到當(dāng)前文件, 安裝 拓展程序
使用 state 修改定時(shí)器
//2. 類組件 class Child extends React.Component {state = {time : new Date() # + }render() {return (<div><h3>我是h3</h3><p>{ this.state.time.toLocaleTimeString() }</p> # + </div>)}componentDidMount () { setInterval(() => {this.setState({ # + time: new Date() # + }) # + }, 1000);} }總結(jié) :
- 函數(shù)組件
- 沒有狀態(tài) ( 沒有自己的私有數(shù)據(jù) )
- 木偶組件, 組件一旦寫好, 基本就不會改變
- 傳參 : function Child( props ) { } , props 只讀
- 類組件
- 有狀態(tài) ( 有自己的私有數(shù)據(jù) state )
- 智能組件, 狀態(tài)發(fā)生改變, 就會更新視圖
- 傳參 :
- this.props
- 優(yōu)點(diǎn)
- 類組件 : 有狀態(tài),有生命周期鉤子函數(shù), 功能比較強(qiáng)大
- 函數(shù)組件 : 渲染更快
- 以后區(qū)分使用 ?
- 就看要不要狀態(tài) , 要狀態(tài)(類組件) , 不要狀態(tài) (函數(shù)組件)
- props 和 state 區(qū)別?
- state - 自己的私有數(shù)據(jù) 類似 vue 里的data
- props - 外界傳進(jìn)來的 類似 vue 里面的props
事件處理
事件注冊
- 以前注冊事件
- react 中注冊事件
- 注冊事件屬性采用的是駝峰的 onClick=…
- 注冊事件的事件處理函數(shù) , 寫為函數(shù)形式,不能為字符串
- onClick={ this.fn }, {} 可以拿到它的原始類型
事件中 this 的處理
- 演示this問題
- bind 和 call 的回憶使用
- 方式1 : bind
- 方式2 : 屬性初始化語法
- 方式3 : 箭頭函數(shù)
- 總結(jié)
- 三者使用場景
點(diǎn)擊事件傳參 + 配合this處理
- 演示效果
- 處理this方式1 : bind
- 處理this方式2 : 屬性初始化語法 – 不能傳參
- 處理this方式3 : 箭頭函數(shù)
獲取事件對象 + 配合this處理
// 方式1 : bind , `處理函數(shù)最后一個(gè)參數(shù)`就是 事件對象 e return <button onClick={this.fn1.bind(this, 123, 456)}>按鈕</button> // 方式2 : 屬性初始化語法 不傳參數(shù) 默認(rèn)形參就是事件對象 e return <button onClick={this.fn2}>按鈕</button> // 方式3 : 箭頭函數(shù) 通過箭頭函數(shù)獲取e,再繼續(xù)傳 return <button onClick={e => this.fn3(e)}>按鈕</button> 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的React基础学习(第二天)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: React基础学习(第一天)
- 下一篇: React基础学习(第三天)