iT邦幫忙

2023 iThome 鐵人賽

DAY 22
0
Modern Web

給前端新手的圖文故事系列 第 22

React 基礎概念學習與認知

  • 分享至 

  • xImage
  •  

NPM 安裝以及 React Project 演練與外部函式庫使用

從安裝 Node.js 開始

Node.js 是沒有瀏覽器的 JavaScript,他是用於建構完整 JavaScript 應用程式的執行環境.
Node 是開源的軟體,可以安裝在 Windows、macOS、Linux 與其他平台上,同時目前在 JavaScript 的全端開發中,他也負責了後端程式的開發,常用的架構是 Express。
使用 React 時其實不需要使用 Node,但必須使用 Node package manager(npm)來安裝相依檔案以及管理環境,他會在安裝 Node 時自動安裝。

Node 官網安裝

若不確定在機器上是否有安裝 Node.js,可以在 終端機或命令視窗中輸入,若是沒有安裝的話,應該會顯示 Command not found

node -v

React.js 基礎介紹與操作演練

React 是 Faecbook 所發布的一套前端開源專案,主要的功能是拿來進行 View 的開發,在架構上其實就是 MVC 的 V,因此這套函式庫具有非常輕薄且高效能的特點,但同時也因其並非作為 MVVM 架構中的 ViewModel 誕生,因此在整體功能面上需要依賴大量外部開源專案輔助,才能完成一個良好的 MVVM 專案.
另外 React 有一個宗旨,也就是在他官網上的 Learn Once, Write Anywhere (學一次就可以寫在任何地方),其原因是他另外一個名為 React Native(https://reactnative.dev/) 的開源專案,可以用來開發接近原生的 iOS 與 Android 專案,使用的方法是接近轉換編譯的做法,樣式撰寫也偏向 CSS 的方式.

特色

  • 單向式的資料流(One-way data flow)
  • 虛擬 DOM 設計(Virtual DOM)
  • 提供 JSX 語法糖
  • 提倡 元件(Component) 開發模式

撰寫方法

在傳統版本的 React 中,我們將使用 class 的操作來建制頁面元件,並且在這裡需要去繼承 React.Component 以獲得更多操作,最後在依靠 return 的方式將建立起來的區塊回傳到虛擬 DOM上,再藉由 ReactDom.render 的函式更新的畫面當中,而很顯然純 React 的寫法在大多人眼中並不是那麼的合理,因此有人提供了一個名為 JSX 的語法結構,讓他在撰寫上個加的貼近我們日常的網頁開發。

原版寫法

// 原先的寫法
class HelloMessage extends React.Component {
  render() {
    return React.createElement(
      "div",
      null,
      "Hello ",
      this.props.name
    );
  }
}

ReactDOM.render(React.createElement(HelloMessage, { name: "Taylor" }), document.getElementById('hello-example'));

使用 JSX 寫法

// 有 JSX 的寫法,並建立 Virtual DOM
class HelloMessage extends React.Component {
  render() {
    return (
      <div>
        Hello {this.props.name}
      </div>
    );
  }
}

ReactDOM.render(
  <HelloMessage name="Taylor" />, // 單向資料流的傳入
  document.getElementById('hello-example')
);

:::warning
注意:JSX 並非 React 原生的操作方式,因此需要額外去使用像是 babel 這類型的編譯器轉換為原本的運作格式。
:::

實際範例操作

上面這個範例看起來非常抽象,那讓我們來引入他們程式來做看看吧!

在 head 中加入 React 的函式庫

<script
  src="https://unpkg.com/react@16/umd/react.development.js"
  crossorigin
></script>
<script
  src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"
  crossorigin
></script>

在 body 中加入等等要變渲染的節點

<div id="root"></div>

原版寫法

// 開始撰寫這令人困惑的東西
    <script>
      class Hello extends React.Component {
        render() {
          return React.createElement('div', null, 'Hello ');
        }
      }

      ReactDOM.render(
        React.createElement(Hello),
        document.getElementById('root'),
      );
    </script>

使用 JSX 寫法

// 開始撰寫這令人困惑的東西
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

<script type="text/babel">
    class Hello extends React.Component {
      render() {
        return <div>Hello {this.props.name}</div>;
      }
    }

   ReactDOM.render(<Hello name='Taylor' />, document.getElementById('root'));
</script>

:::warning
注意:在操作 JSX 的時候,我們若沒有預先進行編譯的話,會需要先引入 babel 的函式庫來協助我們動態編譯,但在實際上這是一個相當耗能的操作,因此在實務上,我們都會在發佈上線前就將程式編譯完成,以減少這不必要的工作量。
:::

各位操作玩這些範例後覺得很困惑是正常的,因為我們目前的範例是 React 最複雜的撰寫方法,同時也是最早期的操作方式,實際上在 React 16.8 推出 Hook 這項新功能之後(2018年),class 的寫法就逐漸減少了,但這邊要注意的是他並不是消失,在一些較舊的專案或是需要較強掌控力的組件中,class 還是具有一定的優勢.

下面就讓我們來看一下較新的寫法吧!基本上我們會使用 Function 的方式去建立組件,在 16.8 的版本推出之前這其實也是很常在使用的,但我們統一將其稱為 Pure Component 也就是純的組件,原因是在 Hook 推出之前,Pure Component 並不具備狀態管理等操作,而是僅能藉由單向資料流來顯示固定資料.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World</title>
    <script src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

    <!-- 不要使用他在正式的專案上 -->
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script type="text/babel">
      function Hello() {
        return <h1>Hello, world!</h1>;
      }
      ReactDOM.render(<Hello />, document.getElementById('root'));
    </script>
  </body>
</html>

以上就是 React 的基本介紹與範例演示,但這裡其實只能算是牛刀小試的內容了,同時在實際開發上,我們也不會傾向使用這種 CDN 載入的方式進行開發,這邊我們主要的學習目的,只是帶大家稍微看一下 React 大概的撰寫方式,一個以 JavaScript 為主導,使用名為 JSX 的語法糖進行語意化,並採納單向數據流的一個 SPA (single-page application) 函式庫.

注意: React 是一套撰寫起來十分自由的語言,以上的寫法均能使程式正常運作,並且居有優缺點,因此很多新手的學習時很容易頻繁碰壁,另外其本質其實就是藉由 JavaScript 進行驅動操作的函示庫,因此 JavaScript 的熟悉程度也會影響對 React 的暸解,但 JavaScript 也很自由就是另外的議題了...

React Project 演練與外部函式庫使用

從零到有搭建 React 專案

其實 React 官方提供了我們非常快捷且便利的方法,那就是 create react app 的指令操作,那為什麼這邊還要特意從零到有尼?究其原因是在使用 Create React App 建構專案之後,其實會有蠻大量用不到的東西被引入到你的專案中,且因為 React 其實作為一個蠻輕巧的函示庫,並沒有那麼多複雜的額外綁定,因此自己建立一下也可以當作是在學習 npm 與 package 的操作。

官方提供方法 (嘗試使用並開啟專案)

官方操作連結
Create React App 是一個適合學習 React 的環境,而且也是使用 React 建立一個全新的 single-page 應用程式的最佳方法。

它會為你設定好開發環境,以便你能夠使用最新的 JavaScript 特性,提供良好的開發者體驗,並且為線上環境最佳化你的應用程式。你需要在你的機器上安裝 Node >= 14.0.0 and npm >= 5.6。要建立項目,請執行:

npx create-react-app my-app
cd my-app
npm start

透過這些簡單的指令應該可以很簡單的搭建出 React App,雖然能如此輕鬆其實是因為 npx 的關係,但在學習階段又何嘗不可尼?

開始搭建自己的專案(可嘗試操作)

其實 npm 是一個非常輕鬆使用的東西,各位同學不妨從頭到尾自己嘗試一下,當然也可以使用目前有的範例檔案,直接運行 npm install
起始範例檔案

那就讓我們先來稍微介紹一下專案結構吧!最簡單的是會需要建立一個 src 進行開發內容的存放,建立一個 public 配置我們的靜態檔案,最後在專案目錄放置一個 package.json,其實就大功告成拉!

- src
    App.js
    index.js
- public
    index.html
package.json

基本專案結構是否簡單到符合預期尼?當然還有內容需要填入,同時在專案運行時也會自動安裝其他套件等,但不可否認的是我們的基本結構可與複雜兩個字沒有任何關係尼

填入專案內容

package.json 說白了其實就是專案的設定擋,裡面可以定義任何你想定義的東西,不過這裡的關鍵是在 dependencies(依賴關係) 中將 react 的運作引入,讓我們可以自由的使用他們

{
  "name": "react-app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build"
  },
  "dependencies": {
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.2"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

App.js 當中會放置我們的主要開發節點,各位可以想像是 「畫面」 的根目錄

function App() {
  return (
    <div>
      <h1>Home Page</h1>
    </div>
  );
}

export default App;

index.js 其實就是我們 src 這個資料夾的最終集結點,並且會最終經過編譯提供一版可運作的 JavaScript 給 public 中的 index.html 進行引入。

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));

作為目標集結點,App 這個組件本身當然也可以在本檔案中進行建立,這邊會額外做引入的原因,只是為了讓整個開發環境更加整潔

index.html 就是單純存放我們的靜態頁面內容,同時也可以進行 SEO 的基礎設計

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

在當中有用到所謂的 import 與 export,這其實也是 ES6 所提供的寫法,功能是將組建或功能等進行匯入與分享,需注意的是如果 export 後面沒有特別帶 default(預設匯出),那在 import 時則需要使用 import {App} from './App' 的方式

在建立完專案的現在,我們在理論上只需要用 npm install 就可以將專案的依賴下載下來了,package 會透過 npm 自動下載所設定的內容,但因為可能會遇到環境與套件安裝等問題,因此可能還需要額外進行一些排錯處理,若真的無法正常操作的同學,可以先使用 npx create-react-app 進行操作


上一篇
前進 React 之前的 JavaScript ES6
下一篇
學習基礎 Hook 使用與副作用(Side Effect)
系列文
給前端新手的圖文故事30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言