為什麼函數式組件需要引進 React?

作者: Calpa Liu
字數:784
出版:2019 年 2 月 26 日
#React.js#Babel#JSX#Readings#Frontend
在編寫組件時,最讓我迷惑的是在我編寫純函數組件,為什麼沒有在代碼裡面調用 React 都需要導入 React。經過一番調研,我發現是因為 JSX 轉譯的設定。不過,人是比較懶惰的,透過安裝 babel-plugin-react-require 插件,達到自動導入 React 的效果。這篇文章將會講述我的調研經歷和一點反思。

比如說我們有一個 App.js 的文件,這裡相等於 Hello World 的設定。

import React from "react";
const App = () => (
  <div>Hello World!!!</div>
);
export default App;

原因

Imgur
Imgur

在 Babel 轉譯我們的 App.js 的時候,會把 JSX 語法糖轉換為 React.createElement 方法。

var App = function App() {
  return React.createElement(
    "div",
    null,
    "Hello World!!!"
  );
};

你可以在 Babel REPL 來看到 Babel 是如何轉譯。

自動引入 React

對於 React 系統的前端項目來說,我們能不能直接寫純函數組件,而不需要在頂部引進 React 語句:import React from 'react';

babel-plugin-react-require
babel-plugin-react-require

答案也是可以的,我們可以透過 babel-plugin-react-require 來自動辨認無狀態組件,然後如果是的話,自動引進 React。

安裝方法

我們可以透過 npm 直接安裝

npm install babel-plugin-react-require --save-dev

然後在 .babelrc 加入 react-require

{
  "plugins": [
    "react-require"
  ]
}

值得注意的是, react-require 需要在 transform-es2015-modules-commonjs 之前引入,因為插件需要 ES2015 模塊化語句來導入 React 到域裡面。

例子

如果我們寫了一個純函數組件,代碼如下:

export default function Component() {
  return (
    <div />
  );
}

babel-plugin-react-require 插件會自動將上面的代碼轉譯為下面的代碼:

import React from 'react';

export default function Component() {
  /* 下面的代碼交給 Babel 繼續編譯 */
  return (
    React.createElement('div')
  );
}

自定義轉譯使用方法

那麼我們可以再想一下,如果用的不是 React,而是其他 React 生態圈裡面的方法的話。比如說 deku,它是一個用來使用純函數和虛擬 DOM 渲染界面的工具庫。它也是 React 生態圈裡面的一份子。

我們能不能改寫轉譯後的方法,不使用 React.createElement 方法?

Imgur
Imgur

答案是可以的。

@babel/plugin-transform-react-jsx 允許我們在文件的頂部加入 /** @jsx 方法名稱 */,或者是在 .babelrc 全局修改

比如說這樣的代碼:

/** @jsx dom */

var { dom } = require("deku");

var profile = <div>
  <img src="avatar.png" className="profile" />
  <h3>{[user.firstName, user.lastName].join(' ')}</h3>
</div>;

會轉譯為下面的代碼:

/** @jsx dom */

var dom = require("deku").dom;

var profile = dom("div", null,
  dom("img", { src: "avatar.png", className: "profile" }),
  dom("h3", null, [user.firstName, user.lastName].join(" "))
);

React 碎片

React Fragment
React Fragment

那麼 React 16.2.0 新增的 Fragments 呢?我們可以透過 /** @jsxFrag 函數名稱 */來達到轉譯後的修改目的。

輸入:

/** @jsx dom */
/** @jsxFrag DomFrag */

var { dom, DomFrag } = require("deku");

var descriptions = items.map(item => (
  <>
    <dt>{item.name}</dt>
    <dd>{item.value}</dd>
  </>
));

輸出:

/** @jsx dom */
/** @jsxFrag DomFrag */

var { dom, DomFrag } = require("deku");

var descriptions = items.map(item => dom(
  DomFrag,
  null,
  dom("dt", null, item.name),
  dom("dd", null, item.value)
));

你可以打開 Babel REPL - React Fragment 來實時調試代碼。

安裝方法

你需要安裝 @babel/plugin-transform-react-jsx 來轉換 JSX 語法,如果沒有安裝的話,那麼你可以透過 npm 安裝它。

npm install --save-dev @babel/plugin-transform-react-jsx

全局修改

.babelrc 寫入下面的片段:

{
  "plugins": ["@babel/plugin-transform-react-jsx"]
}

我們可以透過全局修改 pragma 來修改 React.createElement,

{
  "plugins": [
    ["@babel/plugin-transform-react-jsx", {
      "pragma": "dom", // React.createElement
      "pragmaFrag": "DomFrag", // React.Fragment
      "throwIfNamespace": false, // 如果 XML 名稱空間的標籤名稱被使用的話,拋出異常
      "useBuiltIns": false // 使用 Object.assign 而不是 Babel 內建的擴展工具 (extend)
    }]
  ]
}

參考資料

  1. Why import React from “react” in a functional component?
  2. @babel/plugin-transform-react-jsx
  3. anthonyshort/deku - Github
  4. vslinko/babel-plugin-react-require - Github
關於 Calpa

Calpa 擅長使用 TypeScriptReact.jsVue.js 建立 Responsive Website。

他積極參與開源社區,曾在 2019 年的香港開源大會上擔任講者,提供工作經驗和見解。此外,他也在 GitHub 上公開分享個人博客程式碼,已獲得超過 300 顆星星和 60 個分支的支持。

他熱愛學習新技術,並樂意分享經驗。他相信,唯有不斷學習才能跟上快速演變的技術環境。

熱門文章

最新文章

圖片管理中心
管理圖片資源
IP 查詢
快速查詢和定位 IP 地址的地理位置和相關信息
Python 運行器
無需後端、無需登入,只需打開瀏覽器即可運行 Python 代碼(由 Pyodide 提供支持)
封面圖生成器
自動創建適合各種平台的文章封面圖
原作(青山剛昌)產生器
一鍵創建原作(青山剛昌)的封面圖
日本色彩
探索和使用傳統日本色彩
部落格內容洞察儀表板
以視覺化儀表板方式追蹤文章成效、分享熱度與分類分布,協助創作者掌握內容表現。
蒙特卡羅估算 π
使用蒙特卡羅方法演示 π 值的估算過程
LLM
使用 LLM 模型進行聊天
活動圖生成器
一鍵創建活動的封面圖
Wagmi Card
一鍵創建 Wagmi 的封面圖
Facebook Quote
Facebook Quote
Music Macro Language (MML) Studio
用程式語法編寫旋律,用音符構築想像
Blurhash
一鍵創建 Blurhash
文字分類器
使用 MediaPipe TextClassifier 分類文字
前端工程師免費工具資源
前端工程師免費工具資源
後端工程師免費工具資源
後端工程師免費工具資源
全端工程師免費工具資源
全端工程師免費工具資源
Web3 工程師免費工具資源
Web3 工程師免費工具資源
紫微斗數排盤系統|結合 AI 的命盤性格與事業財務分析生成器
紫微斗數排盤工具,輸入生日與時辰,自動生成完整命盤分析提示(Prompt)。結合最專業紫微理論與 AI 助力,助你深入解析性格、事業、財務與人際課題。免費使用,適合命理師及紫微愛好者。
PixAI Prompt 組合器|快速打造可用於 AI 繪圖的語言拼圖
使用 PixAI 卻不會寫 prompt?這個工具幫你一鍵組裝角色、表情、風格語彙,輸出高品質繪圖提示語句(Prompt),可直接貼入 PixAI 使用。適合插畫師、創作者、AI 新手與 VTuber 角色開發者。