react 擴展

一. setState

setState更新狀態的2種寫法
(1). setState(stateChange, [callback])------對象式的setState
    1.stateChange為狀態改變對象(該對象可以體現出狀態的更改)
    2.callback是可選的回調函數, 它在狀態更新完畢、界面也更新后(render調用后)才被調用
                
(2). setState(updater, [callback])------函數式的setState
    1.updater為返回stateChange對象的函數。
    2.updater可以接收到state和props。
    4.callback是可選的回調函數, 它在狀態更新、界面也更新后(render調用后)才被調用。
總結:
1.對象式的setState是函數式的setState的簡寫方式(語法糖)
2.使用原則:
    (1).如果新狀態不依賴于原狀態 ===> 使用對象方式
    (2).如果新狀態依賴于原狀態 ===> 使用函數方式
    (3).如果需要在setState()執行后獲取最新的狀態數據, 
        要在第二個callback函數中讀取

二. lazyLoad

路由組件的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>

三. 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()
3. 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): 參數為函數, 接收原本的狀態值, 返回新的狀態值, 內部用其覆蓋原來的狀態值
4. Effect Hook
(1). Effect Hook 可以讓你在函數組件中執行副作用操作(用于模擬類組件中的生命周期鉤子)
(2). React中的副作用操作:
        發ajax請求數據獲取
        設置訂閱 / 啟動定時器
        手動更改真實DOM
(3). 語法和說明: 
        useEffect(() => { 
          // 在此可以執行任何帶副作用操作
          return () => { // 在組件卸載前執行
            // 在此做一些收尾工作, 比如清除定時器/取消訂閱等
          }
        }, [stateValue]) // 如果指定的是[], 回調函數只會在第一次render()后執行
    
(4). 可以把 useEffect Hook 看做如下三個函數的組合
        componentDidMount()
        componentDidUpdate()
        componentWillUnmount() 
5. Ref Hook
(1). Ref Hook可以在函數組件中存儲/查找組件內的標簽或任意其它數據
(2). 語法: const refContainer = useRef()
(3). 作用:保存標簽對象,功能與React.createRef()一樣

四. Fragment

使用
<Fragment><Fragment>
<></>
作用

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


五. Context

理解

一種組件間通信方式, 常用于【祖組件】與【后代組件】間通信

使用
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>
注意
在應用開發中一般不用context, 一般都用它的封裝react插件


六. 組件優化

Component的2個問題
  1. 只要執行setState(),即使不改變狀態數據, 組件也會重新render() ==> 效率低

  2. 只當前組件重新render(), 就會自動重新render子組件,縱使子組件沒有用到父組件的任何數據 ==> 效率低

效率高的做法

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

原因

Component中的shouldComponentUpdate()總是返回true

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


七. render props

如何向組件內部動態傳入帶內容的結構(標簽)?
Vue中: 
    使用slot技術, 也就是通過組件標簽體傳入結構  <A><B/></A>
React中:
    使用children props: 通過組件標簽體傳入結構
    使用render props: 通過組件標簽屬性傳入結構,而且可以攜帶數據,一般用render函數屬性
children props
<A>
  <B>xxxx</B>
</A>
{this.props.children}
問題: 如果B組件需要A組件內的數據, ==> 做不到 
render props
<A render={(data) => <C data={data}></C>}></A>
A組件: {this.props.render(內部state數據)}
C組件: 讀取A組件傳入的數據顯示 {this.props.data} 


八. 錯誤邊界

理解:

錯誤邊界(Error boundary):用來捕獲后代組件錯誤,渲染出備用頁面

特點:

只能捕獲后代組件生命周期產生的錯誤,不能捕獲自己組件產生的錯誤和其他組件在合成事件、定時器中產生的錯誤

使用方式:

getDerivedStateFromError配合componentDidCatch

// 生命周期函數,一旦后臺組件報錯,就會觸發
static getDerivedStateFromError(error) {
    console.log(error);
    // 在render之前觸發
    // 返回新的state
    return {
        hasError: true,
    };
}

componentDidCatch(error, info) {
    // 統計頁面的錯誤。發送請求發送到后臺去
    console.log(error, info);
}

九. 組件通信方式總結

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

推薦閱讀更多精彩內容

  • 1. setState setState更新狀態的2種寫法 2. lazyLoad 路由組件的lazyLoad 3...
    AA張_9f53閱讀 210評論 0 0
  • 1. setState setState更新狀態的2種寫法 2. lazyLoad 路由組件的lazyLoad 3...
    硅谷干貨閱讀 340評論 0 5
  • 1. setState更新狀態的2種寫法 總結:1.對象式的setState是函數式的setState的簡寫方式(...
    jiuzhe閱讀 302評論 0 1
  • ## 1. setState ### setState更新狀態的2種寫法 ``` (1). setState(st...
    墨水塵設計閱讀 457評論 0 0
  • setState() setState更新狀態的2種方式 對象式的setState 函數式的setState 對象...
    一號聰明閱讀 314評論 0 0