99偷拍视频精品区一区二,口述久久久久久久久久久久,国产精品夫妇激情啪发布,成人永久免费网站在线观看,国产精品高清免费在线,青青草在线观看视频观看,久久久久久国产一区,天天婷婷久久18禁,日韩动漫av在线播放直播

怎么封裝ReactContextComposer

本篇內容主要講解“怎么封裝React Context Composer”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么封裝React Context Composer”吧!

創新互聯專注于湟中網站建設服務及定制,我們擁有豐富的企業做網站經驗。 熱誠為您提供湟中營銷型網站建設,湟中網站制作、湟中網頁設計、湟中網站官網定制、小程序制作服務,打造湟中網絡公司原創品牌,更為您提供湟中網站排名全網營銷落地服務。

我是如何一步步封裝一個React Context Composer?

動機

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

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

<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的原因是,我們更加習慣從外層到內層的書寫順序。

// 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>

實際體驗后發現,雖然說能用是能用,但是開發體驗差那么一點。它的問題在于,組件入參時傳的value是any類型,這就意味著放棄了ts的靜態類型檢查。在傳參時,由于不會對value做靜態類型檢查,敲起代碼來不僅不會有任何代碼提示,也有可能造成一些比較低級的運行時錯誤。差評!

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

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

舉個例子:

<!-- 調用函數 -->
React.cloneElement(<div/>,{},<span/>);
<!-- 相當于創建了這樣一個結構 -->
<div> 
    <span></span>
</div>

那么下面開始改造,reduceRight的架子不動,改一下入參的類型和reduceRight的回調。

// 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>

經過改造后,我們在傳參時就好像是真的在創建一個組件(當然實際上也創建了組件,只是這個組件本身沒有被渲染到虛擬Dom上,實際渲染上去的是被克隆后的副本)。同時,我們剛才關注的value的靜態類型檢查問題也得到了解決。

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

到此,相信大家對“怎么封裝React Context Composer”有了更深的了解,不妨來實際操作一番吧!這里是創新互聯網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

網站名稱:怎么封裝ReactContextComposer
URL鏈接:http://www.yijiale78.com/article26/gihccg.html

成都網站建設公司_創新互聯,為您提供動態網站定制開發域名注冊小程序開發建站公司全網營銷推廣

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都定制網站網頁設計