jsx-control-statements - jsx的一大利器

pilotage發表於2019-04-10

一、為什麼如此難受?

在我們去寫 JSX 的時候,有時候一直在感嘆為什麼在 JSX 裡面寫不了條件語句,舉個栗子?(為什麼都舉我):

render () {
    return (
        <div>
            {   
                if(true) {
                    <span>渲染我</span>
                } else {
                    <span>不!要渲染我</span>
                }
            }
        </div>
    );
}
複製程式碼

但是!這樣寫是不合法的,JSX 識別不了。在 JSX 中我們只能去寫表示式,這種情況下我們就只能三元表示式去替代咯。

二、用什麼去增強jsx呢?

JSX-Control-Statements 是一個Babel外掛,它擴充套件了 JSX 以新增基本控制語句:條件和迴圈。
它是通過將類似元件的控制語句轉換為它們的 JavaScript 對應語句來實現的:

<If condition={condition()}>Hello World!</If>變為condition() ? 'Hello World!' : null複製程式碼

唯一依賴 JSX-Control-Statements 依賴的是 Babel 。它與React和React Native相容。

三、安裝

PS:因為它是 Babel 的一個外掛,所以我們在使用它的時候要先檢查是否安裝了babel

我們通過 npm 去安裝 jsx-control-statements

npm install --save-dev babel-plugin-jsx-control-statements
複製程式碼

然後你只需要將 JSX-Control-Statements 指定為 Babel 外掛,你通常會在你的外掛中執行 .babelrc

{
  ...
  "plugins": ["jsx-control-statements"]
}
複製程式碼

如果你使用的 transform-react-inline-elements 外掛,把它放在 jsx-control-statements 後邊:

{
  ...
  "plugins": ["jsx-control-statements", "transform-react-inline-elements"]
}
複製程式碼

四、語法

IF標籤

用於表示最簡單的條件邏輯。

// 如果condition的條件為真,則渲染if語句的主體
// 在這裡,這條語句會被轉換成三元表示式,
// { true ? <span>我顯示咯</span> : null }

<If condition={ true }>
  <span>我顯示咯</span>
</If>
複製程式碼

PS:不要使用 <Else /> ,因為它已經被廢棄了。

Choose標籤

這是更高階的一種寫法。

// 這個會被轉換成更復雜的三元表示式

<Choose>
  <When condition={ isShow1 }>
    <span>顯示我?</span>
  </When>
  <When condition={ isShow2 }>
    <span>還是顯示我?</span>
  </When>
  <Otherwise>
    <span>都不滿足那就顯示我吧,我帥!</span>
  </Otherwise>
</Choose>
 
<Choose>
  <When condition={true}>
    <span>顯示我!</span>
  </When>
</Choose>
複製程式碼

<Choose>

作為一個簡單的容器,只允許將 <when><otherwise> 作為子級,每個 <choose> 語句至少需要一個 <when> 塊,<otherwise> 塊是可選的。

<When>

類似於 <IF>

<Otherwise>

都不滿足則渲染這個。

For標籤

// 注意,這裡面我們不要忘記key屬性!!!
// 注意,<for>不能位於react中render函式的根節點!!!
<For each="item" of={ this.props.items }>
    <span key={ item.id }>{ item.title }</span>
</For>

<For each="item" index="idx" of={ [1,2,3] }>
    <span key={ idx }>{ item }</span>
    <span key={ idx + '_2' }>Static Text</span>
</For>
複製程式碼

With標籤

用於為區域性變數賦值。

// 可以用一條<With>語句分配多個變數。定義的變數僅在<With>塊中可用。
// 我們可以在<With>上定義多個屬性 比如:foo={ 47 }  foo2={ 48 } foo3={ 49 }。
// 我們也可以去巢狀使用。
<With foo={ 47 }>
  <span>{ foo }</span>
</With>
複製程式碼

這塊可能稍微的有點費解,大家看下轉換後的程式碼就會清楚了:

// 定義了區域性變數,相當於一個單獨的作用域
{
  (function(foo) {
    return <span>{ foo }</span>
  }).call(this, 47)
}
複製程式碼

五、主要版本

  • 4.xx是一個純Babel外掛,支援Babel >= 7。
  • 3.xx是一個支援Babel >= 6的純Babel外掛。
  • 2.xx是一個支援Babel >= 6的Babel外掛,以及JSTransform使用者。
  • 1.xx是一個Babel外掛,支援Babel <= 5,以及JSTransform使用者。

這曾經支援JSTransform和Babel,但由於不再維護JSTransform,所以不再支援它。你可以在 github.com/alexgillera… 上找到JSTransform版本的程式碼。

六、最後說一點

在我看來,這個外掛會大大加大編譯打包的時間以及程式碼量,如果沒有特殊需求,可以不去使用這個????。