react擴展

1. setState更新狀態的2種寫法

(1). setState(stateChange, [callback])------對象式的setState
        1.stateChange為狀態改變對象(該對象可以體現出狀態的更改)
        2.callback是可選的回調函數, 它在狀態更新完畢、界面也更新后(render調用后)才被調用

(2). setState(updater, [callback])------函數式的setState
        1.updater為返回stateChange對象的函數。
        2.updater可以接收到state和props。
        3.callback是可選的回調函數, 它在狀態更新、界面也更新后(render調用后)才被調用。

總結:
1.對象式的setState是函數式的setState的簡寫方式(語法糖)
2.使用原則:
(1).如果新狀態不依賴于原狀態 ===> 使用對象方式
(2).如果新狀態依賴于原狀態 ===> 使用函數方式
(3).如果需要在setState()執行后獲取最新的狀態數據,
要在第二個callback函數中讀取

2. 路由組件的lazyLoad

//1.通過React的lazy函數配合import()函數動態加載路由組件 ===> 路由組件代碼會被分開打包
const Login = lazy(()=>import('@/pages/Login'))
//2.通過<Suspense>指定在加載得到路由打包文件前顯示一個自定義loading界面
<Suspense fallback={<h1>loading.....</h1>}>
   <Switch>
    <Route path="/xxx" component={Xxxx}/>
    <Redirect to="/login"/>
  </Switch>
</Suspense>

3. Hooks

1.React Hook/Hooks是什么?

(1). Hook是React 16.8.0版本增加的新特性/新語法
(2). 可以讓你在函數組件中使用 state 以及其他的 React 特性

2.三個常用的Hook

(1). State Hook: React.useState()
(2). Effect Hook: React.useEffect()
(3). Ref Hook: React.useRef()

State Hook

(1). State Hook讓函數組件也可以有state狀態, 并進行狀態數據的讀寫操作
(2). 語法: const [xxx, setXxx] = React.useState(initValue)  
(3). useState()說明:
    參數: 第一次初始化指定的值在內部作緩存
    返回值: 包含2個元素的數組, 第1個為內部當前狀態值, 第2個為更新狀態值的函數
(4). setXxx()2種寫法:
    setXxx(newValue): 參數為非函數值, 直接指定新的狀態值, 內部用其覆蓋原來的狀態值
    setXxx(value => newValue): 參數為函數, 接收原本的狀態值, 返回新的狀態值, 內部用其覆蓋原來的狀態值

Effect Hook

(1). Effect Hook 可以讓你在函數組件中執行副作用操作(用于模擬類組件中的生命周期鉤子)
(2). React中的副作用操作:
    發ajax請求數據獲取
    設置訂閱 / 啟動定時器
    手動更改真實DOM
(3). 語法和說明: 
    useEffect(() => { 
      // 在此可以執行任何帶副作用操作
      // useEffect第一個參數中的return的回調相當于componentWillUnmount
      return () => { // 在組件卸載前執行
        // 在此做一些收尾工作, 比如清除定時器/取消訂閱等
      }
    }, [stateValue]) // 檢測數組中數據的變化;如果指定的是空數組[], 回調函數只會在第一次render()后執行;不寫數組,檢測所有數據,數據變化回調函數就會調用
(4). 可以把 useEffect Hook 看做如下三個函數的組合
    componentDidMount()
    componentDidUpdate()
    componentWillUnmount() 

Ref Hook

(1). Ref Hook可以在函數組件中存儲/查找組件內的標簽或任意其它數據
(2). 語法: const refContainer = useRef()
(3). 作用:保存標簽對象,功能與React.createRef()一樣

4. Fragment

可以不用必須有一個真實的DOM根標簽了
使用

<Fragment><Fragment>
// 或者
<></>

5. Context

一種組件間通信方式, 常用于【祖組件】與【后代組件】間通信
在應用開發中一般不用context, 一般都它的封裝react插件

(1).創建Context容器對象:
    const XxxContext = React.createContext() 
(2).渲染子組時,外面包裹xxxContext.Provider, 通過value屬性給后代組件傳遞數據:
    <xxxContext.Provider value={數據}>
      子組件
    </xxxContext.Provider>
(3). 后代組件讀取數據:
  //第一種方式:僅適用于類組件 
  static contextType = xxxContext  // 聲明接收context
  this.context // 讀取context中的value數據 
  //第二種方式: 函數組件與類組件都可以
  <xxxContext.Consumer> 
    {
      value => ( // value就是context中的value數據
        要顯示的內容
      )
    }
  </xxxContext.Consumer>

6. 組件優化

1. Component的2個問題

(1). 只要執行setState(),即使不改變狀態數據, 組件也會重新render()
(2). 只要當前組件重新render(), 就會自動重新render子組件 ==> 效率低

2. 效率高的做法

只有當組件的state或props數據發生改變時才重新render()

3. 原因

Component中的shouldComponentUpdate()總是返回true

4. 解決

(1). 辦法1: 
  重寫shouldComponentUpdate()方法
  比較新舊state或props數據, 如果有變化才返回true, 如果沒有返回false
(2). 辦法2:  
  使用PureComponent
  PureComponent重寫了shouldComponentUpdate(), 只有state或props數據有變化才返回true
  注意: 
    只是進行state和props數據的淺比較, 如果只是數據對象內部數據變了, 返回false  
    不要直接修改state數據, 而是要產生新數據,項目中一般使用PureComponent來優化

重寫shouldComponentUpdate

class Cell extends React.Component {
  shouldComponentUpdate(nextProps, nextState) {
    if (this.props.option === nextProps.option) {
      return false;
    } else {
      return true;
    }
  }
}

7. render props(插槽)

3. 如何向組件內部動態傳入帶內容的結構(標簽)?

Vue中: 
使用slot技術, 也就是通過組件標簽體傳入結構  <AA><BB/></AA>
React中:
使用children props: 通過組件標簽體傳入結構
使用render props: 通過組件標簽屬性傳入結構, 一般用render函數屬性

1. children props

<A>
  <B>xxxx</B>
</A>
{this.props.children}
問題: 如果B組件需要A組件內的數據, ==> 做不到

2. render props

<A render={(data) => <C data={data}></C>}></A>
A組件: {this.props.render(內部state數據)}
C組件: 讀取A組件傳入的數據顯示 {this.props.data} 
import React, { Component } from 'react';

export default class App extends Component {
  render() {
    return (
      <div>
        <A render={(data) => <B data={data}/>} />
      </div>
    );
  }
}

class A extends Component {
  render() {
    const data = { name: 'zs', age: 18 }
    return (
      <div>
        <h3>這里是卡片組件</h3>
        {/* 該處是一個提供給零件的插槽,data相當于具名 */}
        {this.props.render(data)}
      </div>
    )
  }
}

class B extends Component {
  render() {
    console.log(this.props.data)
    return (
      <div>
        <h3>這里是卡片的零件組件</h3>
      </div>
    )
  }
}

8. 錯誤邊界

理解:錯誤邊界:用來捕獲后代組件錯誤,渲染出備用頁面
特點:只能捕獲后代組件生命周期產生的錯誤,不能捕獲自己組件產生的錯誤和其他組件在合成事件、定時器中產生的錯誤
使用方式:getDerivedStateFromError配合componentDidCatch
// 生命周期函數,一旦后臺組件報錯,就會觸發
static getDerivedStateFromError(error) {
    console.log(error);
    // 在render之前觸發
    // 返回新的state
    return {
        hasError: true,
    };
}

componentDidCatch(error, info) {
    // 統計頁面的錯誤。發送請求發送到后臺去
    console.log(error, info);
}
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,983評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,772評論 3 422
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,947評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,201評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,960評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,350評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,406評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,549評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,104評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,914評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,089評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,647評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,340評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,753評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,007評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,834評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,106評論 2 375

推薦閱讀更多精彩內容

  • 1. setState setState更新狀態的2種寫法 2. lazyLoad 路由組件的lazyLoad 3...
    AA張_9f53閱讀 210評論 0 0
  • 1. setState setState更新狀態的2種寫法 2. lazyLoad 路由組件的lazyLoad 3...
    硅谷干貨閱讀 340評論 0 5
  • 一、react 和 vue 的區別是什么? 1、vue是響應式的數據雙向綁定系統,而react是單向數據流,沒有雙...
    Grit_1024閱讀 9,206評論 0 18
  • 1.背景 近期工作原因再次拾起react開發,已經將近兩年沒做過react的開發了,再次開始還是多少有很多需要重新...
    cc_daily閱讀 695評論 0 2
  • Q1:什么是虛擬DOM? 難度::star: 虛擬DOM(VDOM)它是真實DOM的內存表示,一種編程概念,一種模...
    陳二狗想吃肉閱讀 451評論 0 1