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

資訊專欄INFORMATION COLUMN

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

Magicer / 944人閱讀

摘要:精讀源碼一共行,我們分析一下其精妙的方式。更多討論討論地址是精讀新用法如果你想?yún)⑴c討論,請點擊這里,每周都有新的主題,周末或周一發(fā)布。前端精讀幫你篩選靠譜的內(nèi)容。

1 引言

很高興這一期的話題是由 epitath 的作者 grsabreu 提供的。

前端發(fā)展了 20 多年,隨著發(fā)展中國家越來越多的互聯(lián)網(wǎng)從業(yè)者涌入,現(xiàn)在前端知識玲瑯滿足,概念、庫也越來越多。雖然內(nèi)容越來越多,但作為個體的你的時間并沒有增多,如何持續(xù)學(xué)習(xí)新知識,學(xué)什么將會是個大問題。

前端精讀通過吸引優(yōu)質(zhì)的用戶,提供最前沿的話題或者設(shè)計理念,雖然每周一篇文章不足以概括這一周的所有焦點,但可以保證你閱讀的這十幾分鐘沒有在浪費時間,每一篇精讀都是經(jīng)過精心篩選的,我們既討論大家關(guān)注的焦點,也能找到倉庫角落被遺忘的珍珠。

2 概述

在介紹 Epitath 之前,先介紹一下 renderProps。

renderProps 是 jsx 的一種實踐方式,renderProps 組件并不渲染 dom,但提供了持久化數(shù)據(jù)與回調(diào)函數(shù)幫助減少對當(dāng)前組件 state 的依賴。

RenderProps 的概念

react-powerplug 就是一個 renderProps 工具庫,我們看看可以做些什么:


  {({ on, toggle }) => }

Toggle 就是一個 renderProps 組件,它可以幫助控制受控組件。比如僅僅利用 Toggle,我們可以大大簡化 Modal 組件的使用方式:

class App extends React.Component {
  state = { visible: false };

  showModal = () => {
    this.setState({
      visible: true
    });
  };

  handleOk = e => {
    this.setState({
      visible: false
    });
  };

  handleCancel = e => {
    this.setState({
      visible: false
    });
  };

  render() {
    return (
      

Some contents...

Some contents...

Some contents...

); } } ReactDOM.render(, mountNode);

這是 Modal 標(biāo)準(zhǔn)代碼,我們可以使用 Toggle 簡化為:

class App extends React.Component {
  render() {
    return (
      
        {({ on, toggle }) => (
          
          
            

Some contents...

Some contents...

Some contents...

)}
); } } ReactDOM.render(, mountNode);

省掉了 state、一堆回調(diào)函數(shù),而且代碼更簡潔,更語義化。

renderProps 內(nèi)部管理的狀態(tài)不方便從外部獲取,因此只適合保存業(yè)務(wù)無關(guān)的數(shù)據(jù),比如 Modal 顯隱。
RenderProps 嵌套問題的解法

renderProps 雖然好用,但當(dāng)我們想組合使用時,可能會遇到層層嵌套的問題:


  {counter => {
    
      {toggle => {
        ;
      }}
    ;
  }}

因此 react-powerplugin 提供了 compose 函數(shù),幫助聚合 renderProps 組件:

import { compose } from "react-powerplug"

const ToggleCounter = compose(
  ,
  
)


  {(toggle, counter) => (
    
  )}
使用 Epitath 解決嵌套問題

Epitath 提供了一種新方式解決這個嵌套的問題:

const App = epitath(function*() {
  const { count } = yield 
  const { on } = yield 

  return (
    
  )
})

renderProps 方案與 Epitath 方案,可以類比為 回調(diào) 方案與 async/await 方案。Epitath 和 compose 都解決了 renderProps 可能帶來的嵌套問題,而 compose 是通過將多個 renderProps merge 為一個,而 Epitath 的方案更接近 async/await 的思路,利用 generator 實現(xiàn)了偽同步代碼。

3 精讀

Epitath 源碼一共 40 行,我們分析一下其精妙的方式。

下面是 Epitath 完整的源碼:

import React from "react";
import immutagen from "immutagen";

const compose = ({ next, value }) =>
  next
    ? React.cloneElement(value, null, values => compose(next(values)))
    : value;

export default Component => {
  const original = Component.prototype.render;
  const displayName = `EpitathContainer(${Component.displayName ||
    "anonymous"})`;

  if (!original) {
    const generator = immutagen(Component);

    return Object.assign(
      function Epitath(props) {
        return compose(generator(props));
      },
      { displayName }
    );
  }

  Component.prototype.render = function render() {
    // Since we are calling a new function to be called from here instead of
    // from a component class, we need to ensure that the render method is
    // invoked against `this`. We only need to do this binding and creation of
    // this function once, so we cache it by adding it as a property to this
    // new render method which avoids keeping the generator outside of this
    // method"s scope.
    if (!render.generator) {
      render.generator = immutagen(original.bind(this));
    }

    return compose(render.generator(this.props));
  };

  return class EpitathContainer extends React.Component {
    static displayName = displayName;
    render() {
      return ;
    }
  };
};
immutagen

immutagen 是一個 immutable generator 輔助庫,每次調(diào)用 .next 都會生成一個新的引用,而不是自己發(fā)生 mutable 改變:

import immutagen from "immutagen";

const gen = immutagen(function*() {
  yield 1;
  yield 2;
  return 3;
})(); // { value: 1, next: [function] }

gen.next(); // { value: 2, next: [function] }
gen.next(); // { value: 2, next: [function] }

gen.next().next(); // { value: 3, next: undefined }
compose

看到 compose 函數(shù)就基本明白其實現(xiàn)思路了:

const compose = ({ next, value }) =>
  next
    ? React.cloneElement(value, null, values => compose(next(values)))
    : value;
const App = epitath(function*() {
  const { count } = yield ;
  const { on } = yield ;
});

通過 immutagen,依次調(diào)用 next,生成新組件,且下一個組件是上一個組件的子組件,因此會產(chǎn)生下面的效果:

yield 
yield 
yield 
// 等價于

  
    
  

到此其源碼精髓已經(jīng)解析完了。

存在的問題

crimx 在討論中提到,Epitath 方案存在的最大問題是,每次 render 都會生成全新的組件,這對內(nèi)存是一種挑戰(zhàn)。

稍微解釋一下,無論是通過 原生的 renderProps 還是 compose,同一個組件實例只生成一次,React 內(nèi)部會持久化這些組件實例。而 immutagen 在運行時每次執(zhí)行渲染,都會生成不可變數(shù)據(jù),也就是全新的引用,這會導(dǎo)致廢棄的引用存在大量 GC 壓力,同時 React 每次拿到的組件都是全新的,雖然功能相同。

4 總結(jié)

epitath 巧妙的利用了 immutagen 的不可變 generator 的特性來生成組件,并且在遞歸 .next 時,將順序代碼解析為嵌套代碼,有效解決了 renderProps 嵌套問題。

喜歡 epitath 的同學(xué)趕快入手吧!同時我們也看到 generator 手動的步驟控制帶來的威力,這是 async/await 完全無法做到的。

是否可以利用 immutagen 解決 React Context 與組件相互嵌套問題呢?還有哪些其他前端功能可以利用 immutagen 簡化的呢?歡迎加入討論。

5 更多討論
討論地址是:精讀《Epitath - renderProps 新用法》 · Issue #106 · dt-fe/weekly

如果你想?yún)⑴c討論,請點擊這里,每周都有新的主題,周末或周一發(fā)布。前端精讀 - 幫你篩選靠譜的內(nèi)容。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/98354.html

相關(guān)文章

  • 精讀源碼學(xué)習(xí)》

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

    aboutU 評論0 收藏0
  • 精讀《React Hooks》

    摘要:更容易將組件的與狀態(tài)分離。也就是只提供狀態(tài)處理方法,不會持久化狀態(tài)。大體思路是利用共享一份數(shù)據(jù),作為的數(shù)據(jù)源。精讀帶來的約定函數(shù)必須以命名開頭,因為這樣才方便做檢查,防止用判斷包裹語句。前端精讀幫你篩選靠譜的內(nèi)容。 1 引言 React Hooks 是 React 16.7.0-alpha 版本推出的新特性,想嘗試的同學(xué)安裝此版本即可。 React Hooks 要解決的問題是狀態(tài)共享,...

    kohoh_ 評論0 收藏0
  • 精讀《React PowerPlug 源碼

    摘要:今天我們就來解讀一下的源碼。比較有意思,將定時器以方式提供出來,并且提供了方法。實現(xiàn)方式是,在組件內(nèi)部維護一個定時器,實現(xiàn)了組件更新銷毀時的計時器更新銷毀操作,可以認為這種定時器的生命周期綁定了組件的生命周期,不用擔(dān)心銷毀和更新的問題。 1. 引言 React PowerPlug 是利用 render props 進行更好狀態(tài)管理的工具庫。 React 項目中,一般一個文件就是一個類,...

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

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

    Shihira 評論0 收藏0
  • React組件設(shè)計模式-Render-props

    摘要:實際上是讓組件的接收函數(shù),由函數(shù)來渲染內(nèi)容。將通用的邏輯抽象在該組件的內(nèi)部,然后依據(jù)業(yè)務(wù)邏輯來調(diào)用函數(shù)內(nèi)渲染內(nèi)容的函數(shù),從而達到重用邏輯的目的。當(dāng)然,上邊通過傳入了這屬于組件的增強功能。還有也提供了一種新模式來解決這個問題。 寫業(yè)務(wù)時,我們經(jīng)常需要抽象一些使用頻率較高的邏輯,但是除了高階組件可以抽象邏輯,RenderProps也是一種比較好的方法。 RenderProps,顧名思義就是...

    or0fun 評論0 收藏0

發(fā)表評論

0條評論

Magicer

|高級講師

TA的文章

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