react 擴展

一. setState

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

二. lazyLoad

路由組件的lazyLoad
//1.通過React的lazy函數(shù)配合import()函數(shù)動態(tài)加載路由組件 ===> 路由組件代碼會被分開打包
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). 可以讓你在函數(shù)組件中使用 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讓函數(shù)組件也可以有state狀態(tài), 并進行狀態(tài)數(shù)據(jù)的讀寫操作
(2). 語法: const [xxx, setXxx] = React.useState(initValue)  
(3). useState()說明:
        參數(shù): 第一次初始化指定的值在內(nèi)部作緩存
        返回值: 包含2個元素的數(shù)組, 第1個為內(nèi)部當前狀態(tài)值, 第2個為更新狀態(tài)值的函數(shù)
(4). setXxx()2種寫法:
        setXxx(newValue): 參數(shù)為非函數(shù)值, 直接指定新的狀態(tài)值, 內(nèi)部用其覆蓋原來的狀態(tài)值
        setXxx(value => newValue): 參數(shù)為函數(shù), 接收原本的狀態(tài)值, 返回新的狀態(tài)值, 內(nèi)部用其覆蓋原來的狀態(tài)值
4. Effect Hook
(1). Effect Hook 可以讓你在函數(shù)組件中執(zhí)行副作用操作(用于模擬類組件中的生命周期鉤子)
(2). React中的副作用操作:
        發(fā)ajax請求數(shù)據(jù)獲取
        設(shè)置訂閱 / 啟動定時器
        手動更改真實DOM
(3). 語法和說明: 
        useEffect(() => { 
          // 在此可以執(zhí)行任何帶副作用操作
          return () => { // 在組件卸載前執(zhí)行
            // 在此做一些收尾工作, 比如清除定時器/取消訂閱等
          }
        }, [stateValue]) // 如果指定的是[], 回調(diào)函數(shù)只會在第一次render()后執(zhí)行
    
(4). 可以把 useEffect Hook 看做如下三個函數(shù)的組合
        componentDidMount()
        componentDidUpdate()
        componentWillUnmount() 
5. Ref Hook
(1). Ref Hook可以在函數(shù)組件中存儲/查找組件內(nèi)的標簽或任意其它數(shù)據(jù)
(2). 語法: const refContainer = useRef()
(3). 作用:保存標簽對象,功能與React.createRef()一樣

四. Fragment

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

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


五. Context

理解

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

使用
1) 創(chuàng)建Context容器對象:
    const XxxContext = React.createContext()  
    
2) 渲染子組時,外面包裹xxxContext.Provider, 通過value屬性給后代組件傳遞數(shù)據(jù):
    <xxxContext.Provider value={數(shù)據(jù)}>
        子組件
    </xxxContext.Provider>
    
3) 后代組件讀取數(shù)據(jù):

    //第一種方式:僅適用于類組件 
      static contextType = xxxContext  // 聲明接收context
      this.context // 讀取context中的value數(shù)據(jù)
      
    //第二種方式: 函數(shù)組件與類組件都可以
      <xxxContext.Consumer>
        {
          value => ( // value就是context中的value數(shù)據(jù)
            要顯示的內(nèi)容
          )
        }
      </xxxContext.Consumer>
注意
在應用開發(fā)中一般不用context, 一般都用它的封裝react插件


六. 組件優(yōu)化

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

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

效率高的做法

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

原因

Component中的shouldComponentUpdate()總是返回true

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


七. render props

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


八. 錯誤邊界

理解:

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

特點:

只能捕獲后代組件生命周期產(chǎn)生的錯誤挑豌,不能捕獲自己組件產(chǎn)生的錯誤和其他組件在合成事件安券、定時器中產(chǎn)生的錯誤

使用方式:

getDerivedStateFromError配合componentDidCatch

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

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

九. 組件通信方式總結(jié)

組件間的關(guān)系:
  • 父子組件
  • 兄弟組件(非嵌套組件)
  • 祖孫組件(跨級組件)
幾種通信方式:
1.props:
    (1).children props
    (2).render props
2.消息訂閱-發(fā)布:
    pubs-sub、event等等
3.集中式管理:
    redux债蓝、dva等等
4.conText:
    生產(chǎn)者-消費者模式
比較好的搭配方式:
父子組件:props
兄弟組件:消息訂閱-發(fā)布壳鹤、集中式管理
祖孫組件(跨級組件):消息訂閱-發(fā)布、集中式管理饰迹、conText(開發(fā)用的少芳誓,封裝插件用的多)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市啊鸭,隨后出現(xiàn)的幾起案子锹淌,更是在濱河造成了極大的恐慌,老刑警劉巖赠制,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赂摆,死亡現(xiàn)場離奇詭異,居然都是意外死亡钟些,警方通過查閱死者的電腦和手機烟号,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來政恍,“玉大人汪拥,你說我怎么就攤上這事「莺模” “怎么了迫筑?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵宪赶,是天一觀的道長。 經(jīng)常有香客問我脯燃,道長搂妻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任辕棚,我火速辦了婚禮欲主,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘坟募。我一直安慰自己岛蚤,他們只是感情好,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布懈糯。 她就那樣靜靜地躺著涤妒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪赚哗。 梳的紋絲不亂的頭發(fā)上她紫,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天,我揣著相機與錄音屿储,去河邊找鬼贿讹。 笑死,一個胖子當著我的面吹牛够掠,可吹牛的內(nèi)容都是我干的民褂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼疯潭,長吁一口氣:“原來是場噩夢啊……” “哼赊堪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起竖哩,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤哭廉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后相叁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體遵绰,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年增淹,在試婚紗的時候發(fā)現(xiàn)自己被綠了椿访。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡虑润,死狀恐怖赎离,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情端辱,我是刑警寧澤梁剔,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站舞蔽,受9級特大地震影響荣病,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜渗柿,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一个盆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧朵栖,春花似錦颊亮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至门扇,卻和暖如春雹有,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背臼寄。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工霸奕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吉拳。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓质帅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親留攒。 傳聞我的和親對象是個殘疾皇子煤惩,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1. setState setState更新狀態(tài)的2種寫法 2. lazyLoad 路由組件的lazyLoad 3...
    AA張_9f53閱讀 210評論 0 0
  • 1. setState setState更新狀態(tài)的2種寫法 2. lazyLoad 路由組件的lazyLoad 3...
    硅谷干貨閱讀 323評論 0 5
  • 1. setState更新狀態(tài)的2種寫法 總結(jié):1.對象式的setState是函數(shù)式的setState的簡寫方式(...
    jiuzhe閱讀 295評論 0 1
  • ## 1. setState ### setState更新狀態(tài)的2種寫法 ``` (1). setState(st...
    墨水塵設(shè)計閱讀 452評論 0 0
  • setState() setState更新狀態(tài)的2種方式 對象式的setState 函數(shù)式的setState 對象...
    一號聰明閱讀 305評論 0 0