天天看點

#yyds幹貨盤點# 前端關于React的小結

1. 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。

               3.callback是可選的回調函數, 它在狀态更新、界面也更新後(render調用後)才被調用。

   總結:

       1.對象式的setState是函數式的setState的簡寫方式(文法糖)

       2.使用原則:

           (1).如果新狀态不依賴于原狀态 ===> 使用對象方式

           (2).如果新狀态依賴于原狀态 ===> 使用函數方式

           (3).如果需要在setState()執行後擷取最新的狀态資料,

             要在第二個callback函數中讀取

2. 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>

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()

   ```

   #### 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()一樣

   ```

4. Fragment

   ### 使用

     <Fragment><Fragment>

     <></>

   ### 作用

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

5. Context

   ### 了解

   > 一種元件間通信方式, 常用于【祖元件】與【後代元件】間通信

   ### 使用

   ```js

   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插件

6. 元件優化

   ### 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來優化

7. 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}

   <hr/>

8. 錯誤邊界

   #### 了解:

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

   #### 特點:

   隻能捕獲後代元件生命周期産生的錯誤,不能捕獲自己元件産生的錯誤和其他元件在合成事件、定時器中産生的錯誤

   ##### 使用方式:

   getDerivedStateFromError配合componentDidCatch

   ```js

   // 生命周期函數,一旦背景元件報錯,就會觸發

   static getDerivedStateFromError(error) {

       console.log(error);

       // 在render之前觸發

       // 傳回新的state

       return {

           hasError: true,

       };

   }

   componentDidCatch(error, info) {

       // 統計頁面的錯誤。發送請求發送到背景去

       console.log(error, info);

   }

9. 元件通信方式總結

   元件間的關系:

   - 父子元件

   - 兄弟元件(非嵌套元件)

   - 祖孫元件(跨級元件)

   #### 幾種通信方式:

       1.props:

         (1).children props

         (2).render props

       2.消息訂閱-釋出:

         pubs-sub、event等等

       3.集中式管理:

         redux、dva等等

       4.conText:

         生産者-消費者模式

   #### 比較好的搭配方式:

       父子元件:props

       兄弟元件:消息訂閱-釋出、集中式管理