五大知識點帶你梳理react進階知識
- ??前言
- 📧一、props
- 1、PropTypes與DefaultProps應用
- (1)PropTypes
- (2)defaultProps
- 2、props,state與render函式
- 📨二、React中的虛擬DOM
- 1、什么是虛擬DOM
- (1)第一種方案
- (2)第二種方案
- (3)第三種方案
- 2、虛擬DOM中的 Diff 演算法
- 📩三、React中ref的使用
- 📦四、React中的生命周期
- 1、生命周期函式是什么
- 2、生命周期圖例
- 📪五、React中使用CSS影片效果
- 1、普通用法
- 2、react-transition-group
- (1)初次探索
- (2)進階探索
- 📮六、結束語
- 🗳?彩蛋
??前言
對于 react 的表層來說,我們可能經常聽說的是宣告式開發、單向資料流、組件化方式開發等等,那么,進一步來講的話,我們還需要了解的是 react 的 props ,虛擬 DOM 、 ref 以及過渡影片等更多新的知識點,
那在下面的這篇文章中,將來探索關于 react 的進階知識,
叮,下面開始本文的介紹~🤪
📧一、props
1、PropTypes與DefaultProps應用
(1)PropTypes
在 react 中,有時候我們要對組件中的某個屬性進行格式校驗,這個時候我們就需要用到 propTypes ,下面給出一些常見的例子:
// 表示要對TodoItem這個組件做屬性的校驗
TodoItem.propTypes = {
// isRequired 表示必須有值
test: PropTypes.string.isRequired,
// 表示content的propTypes必須是string型別,那string型別的校驗是從PropTypes這個包里面拿到的
content: PropTypes.string,
// 表示detail可以是一個number或者string的語法
detail: PropTypes.arrayOf(PropTypes.number, PropTypes.string),
// 表示deleteItem必須是一個函式
deleteItem: PropTypes.func,
// 表示index必須是一個數字型別
index: PropTypes.number
}
(2)defaultProps
有時候,對于某個屬性來說,我們希望給它個初始值,那這個時候就需要用到 defaultProps ,示例如下:
TodoItem.defaultProps = {
test: 'hello world'
}
上面的代碼表明,當 test 屬性沒有被賦值時,那么它將被賦予一個初始值,值為 hello world ,
2、props,state與render函式
在 react 中,定義一個組件時,經常會看到 props 、 state 和 render ,那他們三者是怎么樣的關系呢?
首先我們要想一個問題:為什么資料發生變化,頁面就會跟著變化呢?
原因在于,頁面是由 render 函式渲染出來的,當資料 state 發生變化時, render 函式就會被重新的執行一次,
同時,當父組件的 render 函式被運行時,它的子組件的 render 都將被重新運行,
📨二、React中的虛擬DOM
1、什么是虛擬DOM
(1)第一種方案
傳統實作虛擬 DOM 的思路:
- 先定義
state,也就是資料; - 撰寫
JSX模板內容; - 把資料和模板進行結合,生成真是的
DOM,進而將內容顯示到頁面上; - 如果遇到要替換資料時,則把資料和模板進行結合,生成真實的
DOM,來替換原始的DOM,
存在缺陷:
- 第一次生成了一個完整的
DOM片段; - 第二次又生成了一個完整的
DOM片段; - 第二次的
DOM替換第一次的DOM,非常耗費性能,
(2)第二種方案
傳統實作虛擬 DOM 的思路改進版:
- 先定義
state,即資料; - 撰寫
JSX模板內容; - 把資料和模板進行結合,生成真實的
DOM,并展示; - 當
state的資料發生改變; - 繼續,把資料和模板進行結合,生成真實的
DOM,并不是直接替換原始的DOM - 將新的
DOM和原始的DOM做比較,并找出差異; - 找到新的
Dom中發生的變化; - 只用新的
DOM中變化的資料,來替換掉老的DOM中的資料,
存在缺陷:
- 性能的提升并不明顯
(3)第三種方案
react 中實作虛擬 DOM 的思路:
-
先定義
state,即資料; -
撰寫
JSX模板內容; -
把資料和模板進行結合,生成虛擬
DOM(虛擬DOM就是一個JS物件,用它來描述真實DOM),👉(損耗了性能)<div id="abc"><span>hello world</span></div> ['div', {id: 'abc'}, ['span', {}, 'hello world']] -
用虛擬
DOM的結構生成真實的DOM,來進行顯示; -
當
state發生變化時,資料 + 模板生成新的虛擬DOM;👉(極大的提升了性能)
<div id="abc"><span>monday</span></div>
['div', {id: 'abc'}, ['span', {}, 'monday']]
- 比較 原始虛擬
DOM和 新的虛擬DOM的區別,找到其中的區別是span中的內容; - 直接操作
DOM,改變span的內容; - 因此,
React的虛擬DOM主要經歷的程序是:JSX→createElement→ 虛擬DOM(JS物件 )→ 真實的DOM,
react 虛擬 DOM 的優點:
- 極大的提升了性能;
- 它使得跨端應用得以實作,這要談到
react中的一個概念,react native; react使用可以撰寫原生應用,像Android和IOS開發,這些都是操作真實DOM;- 而
react使得撰寫這些原生應用得以使用,
2、虛擬DOM中的 Diff 演算法
react對setState的性能優化,它會把多次setState結合成一次setState;- 虛擬
DOM使用diff演算法做比較,只在同層做比較,不跨級做比較; - 同層比對的演算法比較簡單,而演算法簡單帶來的直接好處就是速度非常快;
- 雖然可能會造成
DOM渲染上的一些浪費,但是呢,它也極大的減少了兩個虛擬DOM之間進行比較時,性能上的消耗,
📩三、React中ref的使用
react 中建議的是,希望我們可以用資料驅動的形式來撰寫代碼,盡量不要操作 DOM ,但有時候,我們在做一些極其復雜業務的時候,比如各種震撼影片,不可避免的還是會用到一些原生的 DOM 標簽,因此, ref 幫助我們在 react 中直接獲取 DOM 元素的時候來進行使用,
一般情況下,我們盡量不使用 ref ,如果用 ref 時,會出現各種各樣的問題,同時,當使用 ref 和 setState 時,要注意一些存在的坑,
比如,當 ref 與 setState 相關聯使用時,要注意, setState 是一個異步函式,往往會在同步代碼執行完畢后再執行異步代碼,因此,如果我們希望同步代碼執行順序在 setState 之后時,可以在 setState 接受的第二個引數中,再增加一個回呼函式來進行呼叫,這樣就可以達到我們的效果啦!
render() {
return (
<ul ref={(ul) => this.ul = ul}>
{this.getTodoItem()}
</ul>
)
}
this.setState((prevState) => ({
list: [...prevState.list, prevState.inputValue],
inputValue: ''
}), () => {
console.log(this.ul.querySelectorAll('div').length)
});
📦四、React中的生命周期
1、生命周期函式是什么
所謂生命周期函式,指的是在某一個時刻,組件會自動呼叫執行的函式,那 react 的生命周期都有哪一些呢?
| 階段 | 生命周期 | 含義 |
|---|---|---|
| Mounting | componentWillMount | ①當組件即將被掛載到頁面的時刻時自動執行,即在頁面掛在之前執行;②只在組件被第一次掛在到頁面上才會執行; |
| Mounting/Updation | render | 頁面掛載時被執行 |
| Mounting | componentDidMount | 會在組件被掛載到頁面之后,自動被執行;只在組件被第一次掛在到頁面上才會執行 |
| Updation | componentWillReceiveProps | ①當一個組件從父組件接收引數;②只要父組件的render函式被執行了,子組件的這個生命周期函式就會被執行;③如果這個組件第一次存在于父組件中,不會執行;④如果這個組件之前已經存在于父組件中,才會被執行; |
| Updation | componentWillUpdate | ①組件被更新之前,她會自動執行;②但是它是在shouldComponentUpdate之后被執行,如果shouldComponentUpdate回傳true時,它才執行;如果回傳false,這個函式就不會被執行了, |
| Updation | componentDidUpdate | 組件更新完成之后,它會被執行, |
| Updation | shouldComponentUpdate | 組件被更新之前,它會被自動被執行;此生命周期回傳一個布林值 |
| Unmounting | componentWillUnmount | 當這個組件即將被從頁面中剔除的時候,會被執行, |
2、生命周期圖例
下面用一張圖來展示 react 中生命周期的執行效果:

📪五、React中使用CSS影片效果
1、普通用法
我們來看一下,在 react 中,如何使用 css3 所提供的影片效果,具體代碼如下:
.show {
animation: show-item 2s ease-in forwards;
}
.hide {
animation: hide-item 2s wase-in forwards;
}
@keyframes show-item {
0% {
oppacity: 0;
color: red;
}
50% {
opacity: 0.5;
color: green;
}
100% {
opacity: 1;
color: blue;
}
}
2、react-transition-group
(1)初次探索
有時候,我們可能會想要實作一些很復雜的影片,這個時候 css3 提供的是不夠的,因此,我們還需要一點 js 來加以輔助實作更為復雜的影片,這個時候就有談到 react 中的 react-transition-group 影片,
假設我們想要實作,當點擊一個按鈕時,一行文字漸隱漸顯的實作,那該怎么處理呢?
首先,我們在專案的 src 檔案夾下新增一個組件,命名為 App.js ,具體代碼如下:
import React, { Component, Fragment } from 'react';
import { CSSTransition } from 'react-transition-group';
import './style.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
show: true
}
this.handleToggle = this.handleToggle.bind(this);
}
render() {
return (
<Fragment>
{/* onEntered指的是在某一個時刻會自動執行的一個函式
當入場影片結束時,onEntered將會被執行
*/}
<CSSTransition
in={this.state.show}
timeout={1000}
classNames='fade'
unmountOnExit
onEntered={(el) => { el.style.color = "blue" }}
appear={true}
>
<div>hello</div>
</CSSTransition>
<button onClick={this.handleToggle}>toggle</button>
</Fragment>
)
}
handleToggle() {
this.setState({
show: this.state.show ? false : true
})
}
}
export default App;
之后新增一個 CSS 檔案,命名為 style.css ,具體代碼如下:
/* 入場影片執行的第一個時刻,即剛要入場的這個瞬間 */
/* fade-appear用于實作漸隱漸現的效果 */
.fade-enter,
.fade-appear {
opacity: 0;
}
/* 入場影片執行的第二個時刻,到入場影片執行完成之前的一個時刻 */
.fade-enter-active,
.fade-appear-active {
opacity: 1;
transition: opacity 1s ease-in;
}
/* 當整個入場影片執行完成之后 */
.fade-enter-done {
opacity: 1;
}
/* 表示出場影片執行的第一個時刻 */
.fade-exit {
opacity: 1;
}
/* 整個出場的程序 */
.fade-exit-active {
opacity: 0;
transition: opacity 1s ease-in;
}
/* 當整個出場影片執行完成時 */
.fade-exit-done {
}
此時我們來看下瀏覽器的顯示效果:

(2)進階探索
上面我們只是改變了一項資料,現在,如果我們想要點擊就新增一項過渡效果,這又該如何處理呢?
我們來改造下 App.js 檔案的代碼,具體代碼如下:
import React, { Component, Fragment } from 'react';
import { CSSTransition, TransitionGroup } from 'react-transition-group';
import './style.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
show: true,
list: []
}
this.handleToggle = this.handleToggle.bind(this);
}
render() {
return (
<Fragment>
{/* onEntered指的是在某一個時刻會自動執行的一個函式
當入場影片結束時,onEntered將會被執行
*/}
<TransitionGroup>
{
this.state.list.map((item, index) => {
return (
<CSSTransition
in={this.state.show}
timeout={1000}
classNames='fade'
unmountOnExit
onEntered={(el) => { el.style.color = "blue" }}
appear={true}
key={index}
>
<div>{item}</div>
</CSSTransition>
)
})
}
</TransitionGroup>
<button onClick={this.handleToggle}>toggle</button>
</Fragment>
)
}
handleToggle() {
this.setState((prevState) => {
return {
list: [...prevState.list, 'item']
}
})
}
}
export default App;
此時瀏覽器的運行效果如下:

對于這種型別的影片來說,我們通過 TransitionGroup 對外層進行包裹,之后通過 CSSTransition 對里層進行包裹,進而達到我們最終的效果,
📮六、結束語
在上面這篇文章中,我們講解了 react 中的 props ,同時,還簡單的了解了虛擬 DOM 的內容,除此之外呢,還學習了 ref 的使用,以及 react 中的酷炫的過渡影片,當然,最為重要的一點是, react 中的生命周期函式,
那到這里, react 的進階知識講到這里就結束了,不知道小伙伴們對 react 是否又有進一步的認識呢?
🗳?彩蛋
- 關注公眾號星期一研究室,第一時間關注優質文章,更有面試專欄待你解鎖~
- 如果您覺得這篇文章有幫助到您的的話不妨點贊支持一下喲~~😉
- 以上就是本文的全部內容!我們下期見!🥂🥂🥂
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/316701.html
標籤:其他
