本篇是 React 這套 JavaScript 函式庫的入門教學,介紹如何使用 React 開發互動式的網頁應用程式。
React 是 facebook 官方所維護的開放原始碼 JavaScript 函式庫,可以降低互動式網頁應用程式開發難度,自動處理各種複雜 UI 組件與資料間的連動關係,改善應用程式執行效能。
對於初學者說,建議可以使用以下這份 React 的學習專用範本,直接將這段 HTML 原始碼貼在自己的編輯器中,儲存成 HTML 網頁檔,以瀏覽器打開後即可看到 React 的 hello world 程式執行的結果。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Hello World</title> <!-- 引入 React --> <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <!-- 引入 Babel --> <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> // React 的 JSX 程式碼 ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('root') ); </script> </body> </html>
在接下來的教學內容都可以使用這個 HTML 網頁檔來執行。
使用單一 HTML 範本檔來學習 React 是很方便的作法,但這種方式的程式執行效率較低,不適合用於正式的專案。
若要開發標準的 React 專案,建議使用 create-react-app
這個工具來建立新專案,第一次使用之前請先安裝:
# 安裝 create-react-app npm install -g create-react-app
接著建立新 React 專案:
# 建立新 React 專案
create-react-app my-app
若使用 npm 5.2 以上的版本,可以改用 npx
直接呼叫 create-react-app
來建立新專案:
# 改用 npx(免安裝 create-react-app)
npx create-react-app my-app
建立好新的 React 專案之後,進入專案目錄,啟動開發用伺服器,即可開始撰寫 React 的程式:
# 進入專案目錄 cd my-app # 啟動開發用伺服器 npm start
若要產生可以佈署出去的專案成品,可以執行:
# 建置專案
npm run build
其餘更詳細的專案操作,請直接參考 React 的官方文件。
JSX 是一種 JavaScript 的擴充語言,加入了一些 HTML 標籤的語法,下面這一行就是 JSX 典型的程式碼:
const element = <h1>Hello, world!</h1>;
在多數的應用程式中,UI 都會與資料、事件或其他 UI 有關係,因此 React 架構在設計上就將 HTML 標籤與 JavaScript 控制邏輯合併,以 JSX 來描述 UI 的外觀與運作邏輯,打造出 React 的 UI 組件(components),再用這些 UI 組件堆疊出個應用程式。
開發 React 應用程式時,不一定要使用 JSX 語言,不過通常使用 JSX 會比較方便。
我們可以在 JSX 中以大括號內嵌任何的 JavaScript 運算,例如:
// 普通的 JavaScript function formatName(user) { return user.firstName + ' ' + user.lastName; } const user = { firstName: 'Harper', lastName: 'Perez' }; // JSX 內嵌 JavaScript const element = ( <h1> Hello, {formatName(user)}! </h1> ); // 普通的 JavaScript ReactDOM.render( element, document.getElementById('root') );
在這裡我們將 JSX 內的標籤分成多行來寫(也可以合併為一行),這種狀況建議在頭尾加上小括號,避免不小心造成解析錯誤。
事實上 JSX 的程式碼在經過編譯之後,會轉為普通的 JavaScript 函數來執行,產生特別的 JavaScript 物件,所以 JSX 可以放在判斷式、迴圈中,也可以指定給 JavaScript 的變數、作為函數的參數或傳回值等:
// JSX 與 JavaScript 混合使用 function getGreeting(user) { if (user) { return <h1>Hello, {formatName(user)}!</h1>; } return <h1>Hello, Stranger.</h1>; }
JSX 中的網頁標籤若要指定屬性值,語法跟普通的 HTML 語法類似:
// JSX 指定屬性值 const element = <div tabIndex="0"></div>;
若要以內嵌的 JavaScript 來指定屬性值,則使用大括號將 JavaScript 的運算式包起來放進去:
// JSX 內嵌 JavaScript 指定屬性值 const element = <img src={user.avatarUrl}></img>;
這裡要注意一點:使用大括號時不可以加上引號。
JSX 跟 XML 的規則類似,若遇到非成對的標籤,最後要以 />
結尾。
// 單一標籤 const element = <img src={user.avatarUrl} />;
JSX 可以像普通網頁一樣,包含多個子節點:
// 標籤可含有子節點 const element = ( <div> <h1>Hello!</h1> <h2>Good to see you here.</h2> </div> );
JSX 在內嵌資料時,會自動跳脫(escape)任何特別的字元,所以不用擔心隱碼攻擊(injection attacks):
// 使用者輸入資料 const title = response.potentiallyMaliciousInput; // 安全無虞 const element = <h1>{title}</h1>;
JSX 經過 Babel 編譯之後,會轉換為 React.createElement()
這個 JavaScript 的函數,也就是說以下兩段程式碼的效果是相同的:
// 原始 JSX const element = ( <h1 className="greeting"> Hello, world! </h1> ); // JSX 編譯後的 JavaScript const element = React.createElement( 'h1', {className: 'greeting'}, 'Hello, world!' );
React.createElement()
會進行一些檢查,協助開發者減少錯誤發生的機會,基本上它產生的物件會類似這樣:
// 簡化的 JSX 物件結構 const element = { type: 'h1', props: { className: 'greeting', children: 'Hello, world' } };
這就是典型的 React 元素,React 就是靠著這些資訊來建立與更新 DOM 的。