欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

怎么封裝ReactContextComposer

本篇內(nèi)容主要講解“怎么封裝React Context Composer”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“怎么封裝React Context Composer”吧!

創(chuàng)新互聯(lián)專注于湟中網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供湟中營(yíng)銷型網(wǎng)站建設(shè),湟中網(wǎng)站制作、湟中網(wǎng)頁(yè)設(shè)計(jì)、湟中網(wǎng)站官網(wǎng)定制、小程序制作服務(wù),打造湟中網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供湟中網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。

我是如何一步步封裝一個(gè)React Context Composer?

動(dòng)機(jī)

React的狀態(tài)管理方案有很多,比如Redux、Mobx、Recoil等,目前我只體驗(yàn)過Redux,覺得還是比較笨重一點(diǎn)。因?yàn)槠綍r(shí)寫Hooks比較多,所以我比較傾向于使用Context Provider配合useContext這個(gè)hook來做,這樣也易于狀態(tài)的拆分與組合。這里,我們不討論各家狀態(tài)管理方案的優(yōu)劣,將目光聚焦于在使用Context時(shí)遇到的一個(gè)多層嵌套的問題。

下圖,是我最近在寫的一個(gè)taro + react hooks + ts項(xiàng)目抽離出來的一些代碼。我對(duì)一些全局狀態(tài)進(jìn)行了拆分(拆分的目的是為了減少不必要的重新渲染),然后再把它們嵌套起來。這種寫法讓我回想起了曾經(jīng)被回調(diào)地獄支配的感覺,很難受。因此,我想到了自己去封一個(gè)高階組件,從寫法上把結(jié)構(gòu)“扁平化”。

<LoadingContext.Provider value={{ loading, setLoading }}>
  <UserDataContext.Provider value={{ name: "ascodelife", age: 25 }}>
    <ThemeContext.Provider value={"light"}>
    {/* ....more Providers as long as you want */}
    </ThemeContext.Provider>
  </UserDataContext.Provider>
</LoadingContext.Provider>

最易得的方案

這里,我很快的就寫出了第一種方案,借助reduceRight去完成Provider的嵌套。

這里用reduceRight而不用reduce的原因是,我們更加習(xí)慣從外層到內(nèi)層的書寫順序。

// ContextComposer.tsx
import React from 'react';
type IContextComposerProps = {
  contexts: { context: React.Context<any>; value: any }[];
};
const ContextComposer: React.FC<IContextComposerProps> = ({ contexts, children }) => {
  return (
    <>
      {contexts.reduceRight((child, parent) => {
        const { context, value } = parent;
        return <context.Provider value={value}>{child}</context.Provider>;
      }, children)}
    </>
  );
};
export default ContextComposer;
// App.tsx
<ContextComposer
  contexts={[
    { context: ThemeContext, value: "light" },
    { context: UserDataContext, value: { name: "ascodelife", age: 25 } },
    { context: LoadingContext, value: { loading, setLoading } },
  ]}>
    { children }
</ContextComposer>

實(shí)際體驗(yàn)后發(fā)現(xiàn),雖然說能用是能用,但是開發(fā)體驗(yàn)差那么一點(diǎn)。它的問題在于,組件入?yún)r(shí)傳的value是any類型,這就意味著放棄了ts的靜態(tài)類型檢查。在傳參時(shí),由于不會(huì)對(duì)value做靜態(tài)類型檢查,敲起代碼來不僅不會(huì)有任何代碼提示,也有可能造成一些比較低級(jí)的運(yùn)行時(shí)錯(cuò)誤。差評(píng)!

基于React.cloneElement()的改造方案

為了改造上面的這種方案,我翻到了一個(gè)比較冷門但好用的函數(shù)—— React.cloneElement()。這個(gè)函數(shù)沒有很多需要值得注意的點(diǎn),主要看一眼它的三個(gè)入?yún)?,第一個(gè)是parent element,第二個(gè)是parent props,第三個(gè)是剩余參數(shù)...children,除第一個(gè)參數(shù)外,其他都是可選值。

舉個(gè)例子:

<!-- 調(diào)用函數(shù) -->
React.cloneElement(<div/>,{},<span/>);
<!-- 相當(dāng)于創(chuàng)建了這樣一個(gè)結(jié)構(gòu) -->
<div> 
    <span></span>
</div>

那么下面開始改造,reduceRight的架子不動(dòng),改一下入?yún)⒌念愋秃蛂educeRight的回調(diào)。

// ContextComposer.tsx
import React from 'react';
type IContextComposerProps = {
  contexts: React.ReactElement[];
};
const ContextComposer: React.FC<IContextComposerProps> = ({ contexts, children }) => {
  return (
    <>
      {contexts.reduceRight((child, parent) => {
        return React.cloneElement(parent,{},child);
      }, children)}
    </>
  );
};
export default ContextComposer;
// App.tsx
<ContextComposer
  contexts={[
      <ThemeContext.Provider value={"light"} />,
      <UserDataContext.Provider value={{ name: "ascodelife", age: 25 }} />,
      <LoadingContext.Provider value={{ loading, setLoading }} />,
  ]}>
    { children }
</ContextComposer>

經(jīng)過改造后,我們?cè)趥鲄r(shí)就好像是真的在創(chuàng)建一個(gè)組件(當(dāng)然實(shí)際上也創(chuàng)建了組件,只是這個(gè)組件本身沒有被渲染到虛擬Dom上,實(shí)際渲染上去的是被克隆后的副本)。同時(shí),我們剛才關(guān)注的value的靜態(tài)類型檢查問題也得到了解決。

tips: React.cloneElement(parent,{},child)等價(jià)于React.cloneElement(parent,{children:child}),你知道為什么嗎?

到此,相信大家對(duì)“怎么封裝React Context Composer”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

網(wǎng)站名稱:怎么封裝ReactContextComposer
URL鏈接:http://www.aaarwkj.com/article26/gihccg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動(dòng)態(tài)網(wǎng)站、定制開發(fā)、域名注冊(cè)小程序開發(fā)、建站公司、全網(wǎng)營(yíng)銷推廣

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁(yè)設(shè)計(jì)
国产亚洲精品久在线| 日韩欧美国产精品福利| 人妻少妇性色精品专区av| 麻豆视频国产一区二区| 久久久久四虎国产精品| 亚州精品乱码久久电影| 久久精品免成人费电影| 日韩毛片资源在线观看| 中文字幕精品久久久人妻| 国产av自拍在线免费观看| 日本av一区二区在线| 亚洲一区二区三区经典精品| 少妇二区三区精品视频| 欧美午夜福利视频电影| 国产av一区二区三区野战| 国产自拍精品视频免费观看| 国产亚洲中文字幕91| 色噜噜噜欧美人妻色综合| 久久亚洲天堂色图不卡| 又黄又湿又刺激中文字幕| 免费在线黄色生活大片| 国产91白丝在线观看| 国产成人一区二区二区三区| 97色伦综合在线欧美视频| 久久91亚洲精品中文字幕| 18禁黄网站禁片免费视频| 一级片一区二区中文字幕| 亚洲精品在线观看日本| 成人性生交大片免费男同| 线上免费看黄色亚洲片| 2004年亚洲中文字幕| 精品人妻少妇av一区二区| 人妻有码系列中文字幕专区| 日本经典三级在线视频| 欧美日韩在线视频第三区| 热久久青草精品欧美一区| 中文字幕一区中出爽亚洲| 国产大片在线观看一区二区| 亚洲男人成人性天堂网站| 日韩精品亚洲一级在线观看| 午夜最新福利在线视频|