終究都要學 React 何不現在學呢? - React 基礎 - Hello React - (2)

前言

前面我們快速了解 React 跟 Vue 之間的寫法上差異,所以接下來就是準備正式開始認識並學習 React 囉。

事前提醒

由於接下來我們將會學習 React Hook,而 React 對於一些 JavaScript 的基礎掌握度是比較高的,以下語法會非常建議要學習

  • 箭頭函式
  • 展開運算子
  • 其餘運算子
  • 物件解構
  • 陣列解構
  • 陣列操作方法
    • map
    • filter
    • forEach

當然也不是說 Vue 不會使用到,而是如果你是純粹的新手(小白)沒有使用過 Vue 的話,那麼上面幾個語法會是我強烈建議要熟悉了解的。

除此之外如果你想更深入學習 JavaScript 的話也可以考慮我之前寫的部落格文章

希望我的置入可以讓你幸福的學習 JavaScript。

反正只要大家能幸福就好了啦

React CDN

接下來這邊我們會使用到 React 的 CDN 當作練習,這邊我已經把 React 18 版本的 CDN 寫在這邊,請看下面的網址

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

要這邊請注意我們所使用練習的 React CDN 是開發環境專用的,如果你想改用壓縮版本的話,可以改使用以下

1
2
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>

但是這邊有一件事情要注意,也就是 CDN 的順序不可以 react-dom.js 在前而 react.js 在後,這樣子是會出現 Uncaught TypeError: React is undefined React 錯誤的。

為了避免操作失誤,因此底下這邊我也幫你準備了 CodePen 環境方便讓你可以 Fork 回去開始練習

如果你剛好沒用過 CodePen 的話,也可以考慮參考我這一篇「十分鐘快速入門上手 CodePen(有中文翻譯)」快速認識一下 CodePen,因為接下來會有很多篇範例都是直接放在 CodePen 上。

那麼前面的 script 標籤中有一個 crossorigin 屬性,crossorigin 這個屬性設置主要是告知瀏覽器該 Url 來自哪裡且不發放任何 Client 資訊,而 crossorigin 預設是 anonymous,因此不論是 crossorigin="anonymous"crossorigin 都是一樣的,但這不是這一篇的重點,只是稍微提一下而已,如果你想更了解 crossorigin 的話,建議直接觀看 MDN 的詳細說明會更好。

那麼接著就讓我們開始準備第一個 React 環境吧!

Hello React

還是提醒一下,建議你點一下上方我所提供的 CodePen 環境,因為裡面有我載入好的 React CDN 與 JavaScript 設定,為了避免發生版本上的差異以及環境問題,因此強烈建議你可以 Fork 回自己 CodePen 底下練習唷。

一開始我們必須先建立一個基本的 HTML

1
<div id="app"></div>

你也可以把它當作一個容器來看,主要是讓 React 知道它東西要往哪邊注入,所以概念非常類似容器概念。

接下來是 JavaScript 的部分,我們會先使用 document.querySelector('#app'); 選取剛剛建立的 HTML,如果你想要用 document.getElementById('app'); 也完全沒有任何問題,兩者語法得到的結果都一樣

1
const app = document.querySelector('#app');

到目前為止我們都還在撰寫 JavaScript 的部分,沒有使用到 React 的任何語法,因此我們第一個會使用的語法會是 ReactDOM

ReactDOM 主要來自 react-dom.development.js (or react-dom.production.min.js) 這個 CDN,意旨我們使用 React 的 DOM 生成器,並且會使用它底下的 createRoot 方法,而 createRoot 接收的就是我們剛剛所選取的 document.querySelector('#app'),這樣 React 就會把東西放在這個位置了

1
2
const app = document.querySelector('#app');
ReactDOM.createRoot(app);

這時候畫面上基本上是沒有任何東西的,畢竟我們還沒開始開始寫,只是先做事前準備而已。

接著我們要寫我們要渲染的 DOM,而這渲染過程都會透過 ReactDOMrender() 函式來完成,所以我們會需要將 ReactDOM.createRoot(app); 儲存到一個變數內,以便稍後呼叫 render()

1
2
const app = document.querySelector('#app');
const root = ReactDOM.createRoot(app);

那…render() 要如何使用呢?很簡單,直接把 HTML 寫進去!

1
2
3
4
const app = document.querySelector('#app');
const root = ReactDOM.createRoot(app);

root.render(<h1>Hello React</h1>);

render() 中的 <h1>Hello React</h1> 雖然看起來是 HTML,但實際上名字叫做 JSX,這是一個 HTML 寫在 JavaScript 的方式,中文是 JavaScript 擴充的意思,後面章節我們會在深入認識一下 JSX。

恭喜你已經建立了第一個 React!是不是非常簡單呢?如果你期望上面可以更簡潔一點的話,可以寫成以下

1
2
3
4
ReactDOM.render(
<h1>Hello React</h1>,
document.querySelector('#app')
);

這兩者都是一樣的結果。

只是這邊要特別注意 React 18 之後就不再支援 ReactDOM.render 的方式,而是一率建議改用 ReactDOM.createRoot,因此你可能會在 CodePen 看到以下這一段訊息

Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it’s running React 17. Learn more: https://reactjs.org/link/switch-to-createroot

另一種 Hello React 方式

上面介紹的是使用 JSX 的方式所建立的 React,如果你不想使用 JSX 撰寫的話,另一種方式則是使用 React 的 createElement 方法來建立

1
2
3
4
5
6
7
8
const app = document.querySelector('#app');
const root = ReactDOM.createRoot(app);

const element = React.createElement('h1', {
children: 'Hello React',
})

root.render(element);

雖然結果是一樣的,但實際開發上是不太會用 createElement,而是大多都是使用 JSX。

React.createElement

這邊都已經提到了 createElement 這個方法,因此也稍微提一下是 createElement 可以做什麼,它主要可以傳入三個參數,分別是 HTML 標籤、HTML 屬性與 HTML 內容

1
2
3
4
5
6
7
8
9
10
11
12
const app = document.querySelector('#app');
const root = ReactDOM.createRoot(app);

const element = React.createElement(
'h1', // HTML 標籤
{
className: 'good-react' // HTML 屬性
},
'Hello React' // HTML 內容
)

root.render(element);

你可能也會看到另一種寫法,是採用純物件的形式

1
2
3
4
5
6
7
8
9
const app = document.querySelector('#app');
const root = ReactDOM.createRoot(app);

const element = React.createElement('h1', {
children: 'Hello React',
className: 'good-react'
})

root.render(element);

只是稍微了解一下 createElement 也是不錯的,因為 JSX 本質也是用 createElement 所建立的。

CodePen 撰寫 JSX 注意事項

如果你還是沒有使用我前面所提供的範例環境的話,我會建議你要注意一下你的 CodePen JavaScript 區塊有沒有切換成 Babel 模式

Babel

因為撰寫 JSX 的時候若沒有使用 Babel 模式,是會出現「Uncaught SyntaxError: expected expression, got '<'」 錯誤的,因為瀏覽器並不懂什麼叫做 JSX 唷。

後記

本文將會同步更新到我的部落格