精讀《React 八種前提襯着》

1 弁言

本期精讀的文章是:8 React conditional rendering methods

引見了八種 React 前提襯着體式格局。

模版前提襯着異常罕見,碰到的時刻每每會隨機挑選一種體式格局運用,那末怎樣寫會有較好的保護性呢?先一同相識下有哪八種前提襯着體式格局吧!

2 概述

IF/ELSE

既然 JSX 支撐 js 與 html 混寫,那末交替運用就能夠處理前提襯着的題目:

function render() {
  if (renderComponent1) {
    return <Component1 />;
  } else {
    return <div />;
  }
}

return null

假如不想襯着空元素,最好運用 null 替代空的 div

function render() {
  if (renderComponent1) {
    return <Component1 />;
  } else {
    return null;
  }
}

如許對 React 襯着效力有提拔。

組件變量

將組件賦值到變量,就能夠夠在 return 前恣意修正它了。

function render() {
  let component = null;

  if (renderComponent1) {
    component = <Component1 />;
  }

  return component;
}

三元運算符

三元運算符的語法以下:

condition ? expr_if_true : expr_if_false

用在 JSX 上也很輕易:

function render() {
  return renderComponent1 ? <Component1 /> : null;
}

但三元運算符發生嵌套時,明白本錢會變得很高。

&&

這個是最常用了,由於代碼量起碼。

function render() {
  return renderComponent1 && <Component1 />;
}

IIFE

IIFE 寄義是馬上實行函數,也就是以下代碼:

(function myFunction(/* arguments */) {
  // ...
})(/* arguments */);

當深陷 JSX 代碼中,又想寫一大塊邏輯時,除了回到上方,還能夠運用 IIFE:

function render() {
  return (
    <div>
      {(() => {
        if (renderComponent1) {
          return <Component1 />;
        } else {
          return <div />;
        }
      })()}
    </div>
  );
}

子組件

這是 IIFE 的變種,也就是把這段馬上實行函數替換成一個平常函數:

function render() {
  return (
    <div>
      <SubRender />
    </div>
  );
}

function SubRender() {
  if (renderComponent1) {
    return <Component1 />;
  } else {
    return <div />;
  }
}

IF 組件

做一個前提襯着組件 IF 替代 js 函數的 if

<If condition={true}>
  <span>Hi!</span>
</If>

這個組件完成也很簡樸

const If = props => {
  const condition = props.condition || false;
  const positive = props.then || null;
  const negative = props.else || null;

  return condition ? positive : negative;
};

高階組件

高階組件,就是返回一個新組件的函數,而且吸收一個組件作為參數。

那末我們就能夠在高階組件里寫前提語句,返回差別的組件即可:

function higherOrderComponent(Component) {
  return function EnhancedComponent(props) {
    if (condition) {
      return <AnotherComponent {...props} />;
    }

    return <Component {...props} />;
  };
}

3 精讀

這麼多要領都能完成前提襯着,那末重點在於可讀性與可保護性。

比方經由過程挪用函數完成組件襯着:

<div>{renderButton()}</div>

看上去照樣比較冗餘,假如運用 renderButton getter 定義,我們就能夠夠這麼寫它:

<div>{button}</div>

實在我們想要的就是 button,而不是 renderButton。那末還能夠進一步,痛快封裝成 JSX 組件:

<div>
  <Button />
</div>

是不是要支付這些勤奮,取決於運用的龐雜度。假如運用龐雜度異常高,那你應該只管運用末了一種封裝,讓每一個文件的邏輯只管自力、簡樸。

假如運用龐雜度比較低,那末注重不要過分封裝,以防止把本身繞進去。

所以看來這又是一個沒有牢固答案的題目,挑選何種體式格局封裝,取決於運用龐雜度。

運用龐雜度

對任何代碼封裝,都邑增添這段 銜接邏輯 的龐雜度。

假定無論如何代碼的龐雜度都是恆定穩定的,下面這段代碼,銜接龐雜度為 0,而關於 render 函數而言,邏輯龐雜度是 100:

function render() {
  if (renderComponent) {
    return isOk ? <Component1 /> : <Component2 />;
  } else {
    return <div />;
  }
}

下面這段代碼拆成了兩個函數,邏輯龐雜度對 render SubComponent 來講都是 50,但銜接龐雜度是 50:

function render() {
  if (renderComponent) {
    return <SubComponent>;
  } else {
    return <div />;
  }
}

function SubComponent() {
  return isOk ? <Component1 /> : <Component2 />
}

能夠看到,我們經由過程函數拆分,降低了每一個函數的邏輯龐雜度,但卻進步了銜接龐雜度。

下面來做一個比較,我們假定一個平常的順序員,能夠一次性輕鬆影象 10 個函數。假如再多,函數之間的挪用關聯就會讓人摸不着頭腦。

運用較小時

在運用代碼量比較小時,假定一共有 10 個函數,假如做了邏輯籠統,拆分出了 10 個子函數,那末總邏輯龐雜度穩定,函數變成了 20 個。

此時小王要修正此項目,他須要找到癥結代碼的位置。

假如沒有做邏輯籠統,小王一會兒就記住了 10 個函數,而且很快完成了需求。

假如運用做了邏輯籠統,他須要明白的邏輯龐雜度是穩定的,然則要讀的函數變成了 20 個。小王須要像偵察一樣在線索中不停跳轉,他照樣只找了 10 個癥結函數,但一共也就 20 個函數,邏輯並不龐雜,這值得嗎?

小王內心可能會嘀咕:簡樸的邏輯瞎籠統,害我文件找了半天!

運用較大時

此時運用代碼量比較大,假定一共有 500 個函數,我們不斟酌籠統后帶來的復用優點,假定都沒法復用,那末做了邏輯籠統后,那末總邏輯龐雜度穩定,函數變成了 1000 個。

此時小王接到了需求,終究保護了一個大項目。

小王曉得這個項目很龐雜,從一最先就沒以為能明白項目全貌,所以把本身看成一位偵察,預備一步步探究。

如今有兩種挑選,一種是在未做邏輯籠統時探究,一種是在做過邏輯籠統后探究。

假如沒做邏輯籠統,小王須要面臨 500 個這類函數:

function render() {
  if (renderComponent) {
    return isOk ? <Component1 /> : <Component2 />;
  } else {
    return isReady ? <Component3 /> : <Component4 />;
  }
}

假如做了邏輯籠統,小王須要面臨 1000 個這類函數:

function render() {
  if (renderComponent) {
    return <Component1And2 />;
  } else {
    return <Component3And4 />;
  }
}

在項目巨大后,總函數數目並不會影響對線索的查找,而總線索深度也險些老是牢固的,平常在 5 層擺布。

小王明白 5 個或 10 個函數本錢都差不多,但沒有做邏輯籠統時,這 5 個函數各自參雜了其他邏輯,反而影響對函數的明白。

這時候做邏輯籠統是適宜的。

4 總結

所以總的來講,筆者更偏向運用子函數、子組件、IF 組件、高階組件做前提襯着,由於這四種體式格局都能進步順序的籠統才能。

每每籠統后的代碼會更具有復用性,單個函數邏輯更清楚,在切面編程時更利於明白。

當項目很簡樸時,全部項目的明白本錢都很低,籠統帶來的龐雜度反而讓項目變成了須要切面編程的時刻,就得不償失了。

總結一下:

  • 當項目很簡樸,或許前提襯着的邏輯確認沒法復用時,推薦在代碼頂用 && 或許三元運算符、IIFE 等直接完成前提襯着。
  • 當項目很龐雜時,只管都運用 子函數、子組件、IF 組件、高階組件 等體式格局做更有籠統度的前提襯着。
  • 在做邏輯籠統時,斟酌下項目的龐雜度,防止由於籠統帶來的本錢增添,讓本能夠團體明白的項目變得四分五裂。

5 更多議論

議論地點是:
精讀《React 八種前提襯着》 · Issue #90 · dt-fe/weekly

假如你想介入議論,請點擊這裏,每周都有新的主題,周末或周一宣布。

    原文作者:黃子毅
    原文地址: https://segmentfault.com/a/1190000015317668
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞