国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

精讀《React PowerPlug 源碼》

teren / 3591人閱讀

摘要:今天我們就來解讀一下的源碼。比較有意思,將定時器以方式提供出來,并且提供了方法。實現方式是,在組件內部維護一個定時器,實現了組件更新銷毀時的計時器更新銷毀操作,可以認為這種定時器的生命周期綁定了組件的生命周期,不用擔心銷毀和更新的問題。

1. 引言

React PowerPlug 是利用 render props 進行更好狀態管理的工具庫。

React 項目中,一般一個文件就是一個類,狀態最細粒度就是文件的粒度。然而文件粒度并非狀態管理最合適的粒度,所以有了 Redux 之類的全局狀態庫。

同樣,文件粒度也并非狀態管理的最細粒度,更細的粒度或許更合適,因此有了 React PowerPlug。

比如你會在項目中看到這種眼花繚亂的 state:

class App extends React.PureComponent {
  state = {
    name = 1
    isLoading = false
    isFetchUser = false
    data = {}
    disableInput = false
    validate = false
    monacoInputValue = ""
    value = ""
  }

  render () { /**/ }
}

其實真正 App 級別的狀態并沒有那么多,很多 諸如受控組件 onChange 臨時保存的無意義 Value 找不到合適的地方存儲。

這時候可以用 Value 管理局部狀態:


  {({ value, set, reset }) => (
    <>
      
      
    
  )}
源碼

源碼地址

原料:無

State 只存儲一個屬性 value,并賦初始值為 initial:

export default {
  state = {
    value: this.props.initial
  };
}

方法有 set reset

set 回調函數觸發后調用 setState 更新 value

reset 就是調用 set 并傳入 this.props.initial 即可。

2.2. Toggle

Toggle 是最直接利用 Value 即可實現的功能,因此放在 Value 之后說。Toggle 值是 boolean 類型,特別適合配合 Switch 等組件。

既然 Toggle 功能弱于 Value,為什么不用 Value 替代 Toggle 呢?這是個好問題,如果你不擔心自己代碼可讀性的話,的確可以永遠不用 Toggle。
用法

  {({ on, toggle }) => }
源碼

源碼地址

原料:Value

核心就是利用 Value 組件,value 重命名為 on,增加了 toggle 方法,繼承 set reset 方法:

export default {
  toggle: () => set(on => !on);
}

理所因當,將 value 值限定在 boolean 范圍內。

2.3. Counter

與 Toggle 類似,這也是繼承了 Value 就可以實現的功能,計數器。

用法

  {({ count, inc, dec }) => (
    
  )}
源碼

源碼地址

原料:Value

依然利用 Value 組件,value 重命名為 count,增加了 inc dec incBy decBy 方法,繼承 set reset 方法。

與 Toggle 類似,Counter 將 value 限定在了數字,那么比如 inc 就會這么實現:

export default {
  inc: () => set(value => value + 1);
}

這里用到了 Value 組件 set 函數的多態用法。一般 set 的參數是一個值,但也可以是一個函數,回調是當前的值,這里返回一個 +1 的新值。

2.4. List

操作數組。

用法

  {({ list, pull, push }) => (
    
{list.map({ tag }) => ( pull(value => value === tag)}> {tag} )}
)}
源碼

源碼地址

原料:Value

依然利用 Value 組件,value 重命名為 list,增加了 first last push pull sort 方法,繼承 set reset 方法。

export default {
  list: value,
  first: () => value[0],
  last: () => value[Math.max(0, value.length - 1)],
  set: list => set(list),
  push: (...values) => set(list => [...list, ...values]),
  pull: predicate => set(list => list.filter(complement(predicate))),
  sort: compareFn => set(list => [...list].sort(compareFn)),
  reset
};

為了利用 React Immutable 更新的特性,因此將 sort 函數由 Mutable 修正為 Immutable,push pull 同理。

2.5. Set

存儲數組對象,可以添加和刪除元素。類似 ES6 Set。和 List 相比少了許多功能函數,因此只承擔添加、刪除元素的簡單功能。

用法

需要注意的是,initial 是數組,而不是 Set 對象。


  {({ values, remove, add }) => (
    
      
      {values.map(tag => (
         remove(tag)}>{tag}
      ))}
    
  )}
源碼

源碼地址

原料:Value

依然利用 Value 組件,value 重命名為 values 且初始值為 [],增加了 add remove clear has 方法,保留 reset 方法。

實現依然很簡單,add remove clear 都利用 Value 提供的 set 進行賦值,只要實現幾個操作數組方法即可:

const unique = arr => arr.filter((d, i) => arr.indexOf(d) === i);
const hasItem = (arr, item) => arr.indexOf(item) !== -1;
const removeItem = (arr, item) =>
  hasItem(arr, item) ? arr.filter(d => d !== item) : arr;
const addUnique = (arr, item) => (hasItem(arr, item) ? arr : [...arr, item]);

has 方法則直接復用 hasItem。核心還是利用 Value 的 set 函數一招通吃,將操作目標鎖定為數組類型罷了。

2.6. map

Map 的實現與 Set 很像,類似 ES6 的 Map。

用法

與 Set 不同,Map 允許設置 Key 名。需要注意的是,initial 是對象,而不是 Map 對象。


  {({ set, get }) => (
    
       set("sounds", c)}>
        Game Sounds
      
       set("music", c)}>
        Bg Music
      
      
      
You are {focused ? "focusing" : "not focusing"} the input.
)} 源碼

源碼地址

原料:Value

依然利用 Value 組件,value 重命名為 focused 且初始值為 false,增加了 bind 方法。

bind 方法與 Active 如出一轍,僅是監聽時機變成了 onFocusonBlur

2.10. FocusManager

不知道出于什么考慮,FocusManager 的官方文檔是空的,而且 Help wanted。。

正如名字描述的,這是一個 Focus 控制器,你可以直接調用 blur 來取消焦點。

用法

筆者給了一個例子,在 5 秒后自動失去焦點:


  {({ focused, blur, bind }) => (
    
{ setTimeout(() => { blur(); }, 5000); }} />
You are {focused ? "focusing" : "not focusing"} the input.
)}
源碼

源碼地址

原料:Value

依然利用 Value 組件,value 重命名為 focused 且初始值為 false,增加了 bind blur 方法。

blur 方法直接調用 document.activeElement.blur() 來觸發其 bind 監聽的 onBlur 達到更新狀態的效果。

By the way, 還監聽了 onMouseDownonMouseUp:

export default {
  bind: {
    tabIndex: -1,
    onBlur: () => {
      if (canBlur) {
        set(false);
      }
    },
    onFocus: () => set(true),
    onMouseDown: () => (canBlur = false),
    onMouseUp: () => (canBlur = true)
  }
};

可能意圖是防止在 mouseDown 時觸發 blur,因為 focus 的時機一般是 mouseDown

2.11. Hover

與 Focus 類似,只是觸發時機為 Hover。

用法

  {({ hovered, bind }) => (
    
You are {hovered ? "hovering" : "not hovering"} this div.
)}
源碼

源碼地址

原料:Value

依然利用 Value 組件,value 重命名為 hovered 且初始值為 false,增加了 bind 方法。

bind 方法與 Active、Focus 如出一轍,僅是監聽時機變成了 onMouseEnteronMouseLeave

2.12. Touch

與 Hover 類似,只是觸發時機為 Hover。

用法

  {({ touched, bind }) => (
    
You are {touched ? "touching" : "not touching"} this div.
)}
源碼

源碼地址

原料:Value

依然利用 Value 組件,value 重命名為 touched 且初始值為 false,增加了 bind 方法。

bind 方法與 Active、Focus、Hover 如出一轍,僅是監聽時機變成了 onTouchStartonTouchEnd

2.13. Field

與 Value 組件唯一的區別,就是

用法

這個用法和 Value 沒區別:


  {({ value, set }) => (
     set(e.target.value)} />
  )}

但是用 bind 更簡單:


  {({ bind }) => }
源碼

源碼地址

原料:Value

依然利用 Value 組件,value 保留不變,初始值為 "",增加了 bind 方法,保留 set reset 方法。

與 Value 的唯一區別是,支持了 bind 并封裝 onChange 監聽,與賦值受控屬性 value

export default {
  bind: {
    value,
    onChange: event => {
      if (isObject(event) && isObject(event.target)) {
        set(event.target.value);
      } else {
        set(event);
      }
    }
  }
};
2.14. Form

這是一個表單工具,有點類似 Antd 的 Form 組件。

用法
{({ field, values }) => ( { e.preventDefault(); console.log("Form Submission Data:", values); }} >
)}
源碼

源碼地址

原料:Value

依然利用 Value 組件,value 重命名為 values 且初始值為 {},增加了 setValues field 方法,保留 reset 方法。

表單最重要的就是 field 函數,為表單的每一個控件做綁定,同時設置一個表單唯一 key:

export default {
  field: id => {
    const value = values[id];
    const setValue = updater =>
      typeof updater === "function"
        ? set(prev => ({ ...prev, [id]: updater(prev[id]) }))
        : set({ ...values, [id]: updater });

    return {
      value,
      set: setValue,
      bind: {
        value,
        onChange: event => {
          if (isObject(event) && isObject(event.target)) {
            setValue(event.target.value);
          } else {
            setValue(event);
          }
        }
      }
    };
  }
};

可以看到,為表單的每一項綁定的內容與 Field 組件一樣,只是 Form 組件的行為是批量的。

2.15. Interval

Interval 比較有意思,將定時器以 JSX 方式提供出來,并且提供了 stop resume 方法。

用法

  {({ start, stop }) => (
    <>
      
The time is now {new Date().toLocaleTimeString()}
)}
源碼

源碼地址

原料:無

提供了 start stop toggle 方法。

實現方式是,在組件內部維護一個 Interval 定時器,實現了組件更新、銷毀時的計時器更新、銷毀操作,可以認為這種定時器的生命周期綁定了 React 組件的生命周期,不用擔心銷毀和更新的問題。

具體邏輯就不列舉了,利用 setInterval clearInterval 函數基本上就可以了。

2.16. Compose

Compose 也是個有趣的組件,可以將上面提到的任意多個組件組合使用。

用法

  {(counter, toggle) => (
    
  )}
源碼

源碼地址

原料:無

通過遞歸渲染出嵌套結構,并將每一層結構輸出的值存儲到 propsList 中,最后一起傳遞給組件。這也是為什么每個函數 value 一般都要重命名的原因。

在 精讀《Epitath 源碼 - renderProps 新用法》 文章中,筆者就介紹了利用 generator 解決高階組件嵌套的問題。

在 精讀《React Hooks》 文章中,介紹了 React Hooks 已經實現了這個特性。

所以當你了解了這三種 "compose" 方法后,就可以在合適的場景使用合適的 compose 方式簡化代碼。

3. 總結

看完了源碼分析,不知道你是更感興趣使用這個庫呢,還是已經躍躍欲試開始造輪子了呢?不論如何,這個庫的思想在日常的業務開發中都應該大量實踐。

另外 Hooks 版的 PowerPlug 已經 4 個月沒有更新了(非官方):react-powerhooks,也許下一個維護者/貢獻者 就是你。

討論地址是:精讀《React PowerPlug》 · Issue #129 · dt-fe/weekly

如果你想參與討論,請點擊這里,每周都有新的主題,周末或周一發布。前端精讀 - 幫你篩選靠譜的內容。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/102068.html

相關文章

  • 精讀《Epitath 源碼 - renderProps 新用法》

    摘要:精讀源碼一共行,我們分析一下其精妙的方式。更多討論討論地址是精讀新用法如果你想參與討論,請點擊這里,每周都有新的主題,周末或周一發布。前端精讀幫你篩選靠譜的內容。 1 引言 很高興這一期的話題是由 epitath 的作者 grsabreu 提供的。 前端發展了 20 多年,隨著發展中國家越來越多的互聯網從業者涌入,現在前端知識玲瑯滿足,概念、庫也越來越多。雖然內容越來越多,但作為個體的...

    Magicer 評論0 收藏0
  • 精讀源碼學習》

    摘要:精讀原文介紹了學習源碼的兩個技巧,并利用實例說明了源碼學習過程中可以學到許多周邊知識,都讓我們受益匪淺。討論地址是精讀源碼學習如果你想參與討論,請點擊這里,每周都有新的主題,周末或周一發布。 1. 引言 javascript-knowledge-reading-source-code 這篇文章介紹了閱讀源碼的重要性,精讀系列也已有八期源碼系列文章,分別是: 精讀《Immer.js》源...

    aboutU 評論0 收藏0
  • 精讀《怎么用 React Hooks 造輪子》

    摘要:可以看到,這樣不僅沒有占用組件自己的,也不需要手寫回調函數進行處理,這些處理都壓縮成了一行。效果通過拿到周期才執行的回調函數。實現等價于的回調僅執行一次時,因此直接把回調函數拋出來即可。 1 引言 上周的 精讀《React Hooks》 已經實現了對 React Hooks 的基本認知,也許你也看了 React Hooks 基本實現剖析(就是數組),但理解實現原理就可以用好了嗎?學的是...

    Shihira 評論0 收藏0
  • 精讀react-easy-state 源碼

    摘要:會自動觸發函數內回調函數的執行。因此利用并將依賴置為使代碼在所有渲染周期內,只在初始化執行一次。同時代碼里還對等公共方法進行了包裝,讓這些回調函數中自帶效果。前端精讀幫你篩選靠譜的內容。 1. 引言 react-easy-state 是個比較有趣的庫,利用 Proxy 創建了一個非常易用的全局數據流管理方式。 import React from react; import { stor...

    curlyCheng 評論0 收藏0
  • 徹底理清前端單頁面應用(SPA)的實現原理 【精讀源碼

    showImg(https://segmentfault.com/img/bVbvOmp?w=1612&h=888); 隨著React Vue前端框架的興起,出現了Vue-router,react-router-dom等前端路由管理庫,利用他們構建出來的單頁面應用,也是越來越接近原生的體驗,再也不是以前的點擊標簽跳轉頁面,刷新整個頁面了,那么他們的原理是什么呢? 優質gitHub開源練手項目: ...

    xiaodao 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<