目前這個系列已挑選ChatGPT、前端&React相關章節出版成書!
感謝大家的閱讀與支持!
《用 ChatGPT 詠唱來點亮 React & 前端技能樹》
歷經重新整理、校正、編排、與修改後,讓章節內容之間的銜接更平順,除了補充上更多的解說之外,甚至有部分章節為重新撰寫的內容,讓理解變得更輕鬆!
目前已在天瓏書局、博客來、金石堂等通路都買得到了! 也有電子書的選擇!
歡迎各位點擊連結選購,謝謝大家~
今天開始要來挑戰,能不能讓ChatGPT來引領React入門
在這個章節之前,我會預設身上的技能至少有基本以下這些
更好的話是:
另外因為我自己是先會jQuery + Html 的寫法,才學習React的
我在我接下來的自訂指令中,有提到我會jQuery和TypeScript
所以內容中可能會出現一些jQuery的寫法與React的寫法對照
或是我主動指定要ChatGPT提供對照的寫法
最後在安裝套件、建立基礎專案的時候,會需要一點點指令:cd
以上沒問題的話,就要Go Go了
當然可以!以下是一份針對初學者的 React 學習文件,我會以你擅長的 TypeScript 來進行說明,同時也會以 jQuery 為參考。
React 初學者教學文件
步驟一:安裝環境
首先,確保你已經安裝了 Node.js 和 npm。你可以到官方網站下載並安裝最新版本。
步驟二:建立新的 React 專案
打開終端機,選擇一個你想要建立專案的目錄,然後輸入以下指令:
npx create-react-app my-react-app --template typescript
這將會建立一個使用 TypeScript 的 React 專案。
步驟三:了解 React 基本概念
React 是一個用於建立用戶介面的 JavaScript 函式庫。以下是一些重要的概念:
- Component(元件):React 應用由許多小的元件組成,每個元件負責渲染特定部分的畫面。
- State(狀態):狀態代表了一個元件的資料,它會影響元件的渲染結果。
- Props(屬性):Props 是從父元件傳遞到子元件的資料,用於定義元件的特性。
步驟四:建立你的第一個 React 元件
在
src
目錄下建立一個新的 TypeScript 檔案,例如HelloWorld.tsx
,然後撰寫以下程式碼:import React from 'react'; interface HelloWorldProps { name: string; } const HelloWorld: React.FC<HelloWorldProps> = ({ name }) => { return <div>Hello, {name}!</div>; } export default HelloWorld;
這是一個簡單的 React 元件,接收一個名字(
name
)作為屬性。步驟五:使用你的 React 元件
在你的應用中,你可以透過以下方式使用這個元件:
import React from 'react'; import HelloWorld from './HelloWorld'; const App: React.FC = () => { return ( <div className="App"> <HelloWorld name="John" /> </div> ); } export default App;
這個範例中,我們匯入了
HelloWorld
元件,然後在App
元件中使用它。步驟六:啟動你的應用
在終端機中,輸入以下指令以啟動你的應用:
npm start
這將會開啟一個預覽伺服器,你可以在瀏覽器中看到你的 React 應用運行。
這是一個簡單的入門教學,希望對你有幫助!如果你有任何問題或需要更進一步的協助,隨時告訴我。
喔喔喔,有點快有點多,而且他把NodeJS與npm的安裝那塊輕描淡寫的帶過去了
我們把節奏放慢,詢問NodeJS相關問題與安裝步驟
Node.js 是一個基於 Chrome V8 引擎的 JavaScript 執行環境,它允許你在伺服器端運行 JavaScript 代碼。npm 則是 Node.js 的套件管理器,用於安裝、共享和管理 JavaScript 套件。
以下是安裝 Node.js 和 npm 的步驟:
前往官方網站下載 Node.js
前往 Node.js 官方網站,這個網站會依據你的作業系統自動推薦合適的版本。點選下載按鈕。
安裝 Node.js
Windows: 下載完執行安裝程式,按照提示一直點選 "Next" 直到完成安裝。
macOS: 下載完後會得到一個
.pkg
檔案,雙擊打開並按照指示進行安裝。Linux: 使用適合你發行版的包管理器進行安裝。例如,在 Ubuntu 中可以使用以下指令:
sudo apt update sudo apt install nodejs npm
驗證安裝
打開終端機(命令提示字元)並輸入以下指令來檢查 Node.js 和 npm 是否正確安裝:
node -v npm -v
如果安裝成功,你將會看到對應的版本號。
現在你已經成功安裝了 Node.js 和 npm,可以開始進行 React 或其他 JavaScript 開發了!如果你有任何問題或需要進一步的幫助,隨時告訴我。
OKOK
安裝好,開啟終端機Terminal/命令提示字元CMD,用cd 的指令移動到指定資料夾
執行 npx create-react-app my-react-app --template typescript
(my-react-app
的部分是可以自己取名字的,但我故意維持,還有這個指令是含typeScript設定的)
接著就會開始跑起來
沒有安裝過create-react-app
的還會問你要不要安裝,按y就是了
接著就會得到一大包零零叩叩的專案檔案
原先學習網頁基本時,只有html檔、JS檔/TS檔、CSS檔這三種檔案
但執行指令之後,建置出來的東西有很多陌生的東西
一時之間很可能會手足無措
因此來詢問ChatGPT這些初始檔案是什麼、作用是什麼
當你執行
npx create-react-app my-react-app --template typescript
之後,會生成一個初始的 React 專案,以下是該專案的檔案結構與各檔案的作用:
my-react-app/
- 這是你的 React 專案的主目錄。
node_modules/
- 這個目錄包含了所有的第三方套件和相依項目,這些套件是你在專案中使用的庫和工具,如 React, ReactDOM, TypeScript 等。
public/
- 這個目錄包含了公開的靜態檔案,如 HTML 檔案、圖片、字型等。
index.html
是你的 React 應用的主頁面,它包含了一個div
元素,React 將會把你的應用程式渲染到這個元素中。src/
- 這個目錄包含了你的 React 應用的源代碼。
App.tsx
是你的主要應用程式元件,它是一個範例元件,你可以根據需要進行修改或擴展。index.tsx
是你的應用程式的進入點,它將會載入App.tsx
並將其渲染到public/index.html
中的根元素。react-app-env.d.ts
包含了 React 應用程式的類型定義,你通常不需要直接修改這個檔案。reportWebVitals.ts
是用來監控應用程式的性能的工具。package.json
和package-lock.json
package.json
包含了你的專案的相關設定和套件相依項目的清單。package-lock.json
是用來確保在不同的環境中安裝相同版本的套件,通常你不需要手動修改這個檔案。tsconfig.json
- 這是 TypeScript 的設定檔,它定義了 TypeScript 編譯器的行為,包括哪些檔案需要編譯、如何處理模組、設定目標環境等。
.gitignore
- 這個檔案列出了不需要納入版本控制的檔案和目錄,通常包括
node_modules
、編譯後的檔案等。- 其他檔案
- 其他可能還會包括一些配置檔案或工具檔案,這取決於你的專案配置和需求。
這些檔案和目錄構成了一個基本的 React 專案,你可以在這個基礎上開始開發你的應用程式。如果你對於任何特定的檔案或概念有疑問,請隨時告訴我。
綜合上述,實際上在寫React的時候,主要要處理並更動的檔案是App.tsx
目前App.tsx
的內容只是範例,要替換成我們自己撰寫的內容就從這裡做起
並根據第一個ChatGPT給我們的HelloWorld範例:
步驟四:建立你的第一個 React 元件
在
src
目錄下建立一個新的 TypeScript 檔案,例如HelloWorld.tsx
,然後撰寫以下程式碼:import React from 'react'; interface HelloWorldProps { name: string; } const HelloWorld: React.FC<HelloWorldProps> = ({ name }) => { return <div>Hello, {name}!</div>; } export default HelloWorld;
這是一個簡單的 React 元件,接收一個名字(
name
)作為屬性。步驟五:使用你的 React 元件
在你的應用中,你可以透過以下方式使用這個元件:
import React from 'react'; import HelloWorld from './HelloWorld'; const App: React.FC = () => { return ( <div className="App"> <HelloWorld name="John" /> </div> ); } export default App;
這個範例中,我們匯入了
HelloWorld
元件,然後在App
元件中使用它。
所以我們照著上面,在src下建立一個HelloWorld.tsx
然後也把App.tsx的內容換成他所說的內容
並在終端機中,該目錄中輸入 npm start
跑了一些文字之後,會突然幫你開啟瀏覽器,然後出現localhost:3000 的頁面
內容與HTML結構如下
好像加減能明白影響這個內容的關鍵,就是我們剛剛撰寫的HelloWorld.tsx
和App.tsx
但我們目前對React的語法仍然一無所知,只知道好像寫了像是HTML的東西
因此請ChatGPT針對上述語法做詳細解說
當然!我會根據你提供的範例
HelloWorld.tsx
和App.tsx
來進行 React 語法結構的詳解。
HelloWorld.tsx
import React from 'react'; interface HelloWorldProps { name: string; } const HelloWorld: React.FC<HelloWorldProps> = ({ name }) => { return <div>Hello, {name}!</div>; } export default HelloWorld;
詳解:
import React from 'react';
:這行程式碼是用來匯入 React 套件。在 React 中,我們通常需要先引入 React。interface HelloWorldProps
:這是一個 TypeScript 的介面(interface),用來定義HelloWorld
元件的屬性(props)。在這裡,我們定義了一個屬性name
,它的類型是字串。const HelloWorld: React.FC<HelloWorldProps> = ({ name }) => {...}
:這是一個 React 函式元件(functional component)的定義。
const HelloWorld
宣告了一個名為HelloWorld
的常數,這個常數代表了這個元件。: React.FC<HelloWorldProps>
:這部分指定了這個元件接受的屬性類型,並且它是一個函式元件(Functional Component)。= ({ name }) => {...}
:這是一個箭頭函式,它接受一個參數{ name }
,這裡使用了解構賦值來提取props
物件中的name
。return <div>Hello, {name}!</div>;
:這是這個元件的回傳值,它會返回一個包含文字的<div>
元素,其中包含了name
的值。export default HelloWorld;
:這行程式碼用來匯出HelloWorld
元件,以便在其他地方可以引入和使用它。
App.tsx
import React from 'react'; import HelloWorld from './HelloWorld'; const App: React.FC = () => { return ( <div className="App"> <HelloWorld name="John" /> </div> ); } export default App;
詳解:
import React from 'react';
:這是引入 React 套件,和上述HelloWorld.tsx
中的作用相同。import HelloWorld from './HelloWorld';
:這行程式碼用來引入之前定義的HelloWorld
元件。const App: React.FC = () => {...}
:這是定義了一個名為App
的函式元件。
const App
宣告了一個名為App
的常數,它代表了這個元件。: React.FC
指定這個元件是一個函式元件。= () => {...}
是一個箭頭函式,這個元件沒有接受任何參數。return (...)
:這是這個元件的回傳值,它返回了一個 JSX 元素,包含了一個<div>
元素,裡面包含了之前引入的HelloWorld
元件。<HelloWorld name="John" />
:這是使用了HelloWorld
元件,並傳遞了一個名為name
的屬性,值為"John"
。export default App;
:這行程式碼用來匯出App
元件,以便在其他地方可以引入和使用它。這就是你提供的範例程式碼的詳解。如果你有任何進一步的問題或需要協助,請隨時告訴我!
上述提到了很多陌生的名詞
像是「JSX 元素」、「元件(Component)」、「元件的屬性(props)」、「函式元件(Functional Component)」
在最初ChatGPT講述的React三大核心概念:
Component(元件)、State(狀態)、Props(屬性)
似乎就出現了其中兩個,卻沒有提過JSX 元素
我們先從JSX元素開始詢問起
JSX(JavaScript XML)是一種語法擴展,它允許我們在 JavaScript 中像編寫 HTML 一樣來描述 UI 元素的樣子。
在 React 中,我們可以使用 JSX 來建構 UI 界面。例如:
const element = <h1>Hello, World!</h1>;
在這個例子中,
<h1>Hello, World!</h1>
就是一個 JSX 元素。它看起來類似於 HTML,但實際上是 JavaScript 的語法。在執行時,JSX 會被轉換成對應的 JavaScript 代碼。上面的例子在執行時會被轉換成:
const element = React.createElement('h1', null, 'Hello, World!');
這裡的
React.createElement
是 React 提供的一個方法,它用來創建一個 React 元素。使用 JSX 可以讓我們在 React 中更直觀地編寫 UI,它可以包含 HTML 標籤、自定義 React 元件,甚至可以在
{}
中插入 JavaScript 運算式。例如:
const name = 'John'; const element = <h1>Hello, {name}!</h1>;
這樣的 JSX 元素可以動態地根據變數
name
來生成相應的內容。總的來說,JSX 讓我們可以以一種簡潔明瞭的方式描述 UI,並且它可以和 JavaScript 代碼很好地結合在一起,這使得 React 在構建複雜的 UI 介面時變得非常方便。
所以JSX是在JS中,用類似HTML的語法描繪UI (畫面、使用者介面)
可以直接用{}
來插入JS的變數、運算式等等
而JSX本身的結果是一個物件,可以存在變數中,也可以當作回傳值
是時候問問那麼什麼是元件了
在 React 中,元件(Component)是一個可以獨立重複使用的 UI 單元,它將 UI 介面封裝在一個獨立的模組中,這使得應用程式更容易維護和擴展。元件可以是函式型元件(Functional Component)或類別型元件(Class Component)。
函式型元件(Functional Component):
函式型元件是一種以函式的方式定義的 React 元件。它是 React 16.8 版本引入的 Hooks 特性後,主要用於定義簡單的元件。函式型元件是純函式,它接收一些屬性(props)並返回一個 JSX 元素。
現在讓我們以你提供的
HelloWorld.tsx
範例來說明函式型元件:import React from 'react'; interface HelloWorldProps { name: string; } const HelloWorld: React.FC<HelloWorldProps> = ({ name }) => { return <div>Hello, {name}!</div>; } export default HelloWorld;
HelloWorld
是一個函式型元件的定義,它接收一個名為HelloWorldProps
的介面(interface)作為屬性(props)的類型定義。- 函式內部使用箭頭函式定義,它接收一個物件解構
{ name }
作為輸入,這個物件中包含了傳遞給元件的屬性,這裡只有一個name
。- 函式的返回值是一個 JSX 元素,它描述了這個元件渲染時的外觀,這裡是一個包含文字的
<div>
元素。類別型元件(Class Component):
類別型元件是 React 最早的元件定義方式,它是一個 JavaScript 類別,繼承自 React 的基礎類別
React.Component
,並覆寫一些生命週期方法,如render()
。雖然在新的 React 專案中,函式型元件和 Hooks 更受歡迎,但類別型元件仍然被廣泛使用。如果需要,我們也可以使用你提供的範例中的
App.tsx
來解釋類別型元件,請讓我知道是否需要詳細解釋類別型元件的範例。
所以上述我們的範例,都是「函式型元件(Functional Component)」
就是撰寫一個function,定義他的輸入型別(物件),然後輸出是JSX元素
這樣的function就可以作為一個元件
ChatGPT提到了,另外一種方式「類別型元件」是最早的定義方式
現在是「函式型元件」更受歡迎
確實,目前Functional Component是主流,也許Class的寫法會逐漸淘汰掉
官方新版的教學,也直接從Functional Component教起(舊版會教Class的)
如果有興趣可以自行去追問ChatGPT,我們這邊就不深加探究
然後看看範例中的元件定義:
const HelloWorld: React.FC<HelloWorldProps> = ({ name }) => {
return <div>Hello, {name}!</div>;
}
這裡用了好幾個比較複雜的語法,像是TypeScript的型別定義、ES6的箭頭函式、ES6解構
我們再放慢腳步,請ChatGPT把範例變成更容易理解的樣子
當然可以!我將以更簡單的方式來解釋:
// 定義一個名為 HelloWorld 的函式型元件,接收一個名為 name 的屬性 function HelloWorld(props) { // 從 props 中取得名字(name)屬性的值 const name = props.name; // 返回一個包含文字的 div 元素 return <div>Hello, {name}!</div>; } export default HelloWorld;
在這個簡化的版本中:
- 我們使用了一個簡單的函式型元件
function HelloWorld(props)
,它接收一個props
物件。- 從
props
中取得name
屬性的值,並賦值給一個名為name
的變數。- 最後,返回一個包含文字的
<div>
元素,文字部分使用了{name}
來顯示傳入的名字。這個版本相對於前一個版本,去掉了 TypeScript 的型別定義和箭頭函式,使得程式碼更為簡單易懂。但需要注意的是,這種簡化版本的寫法可能會失去一些型別檢查的功能(因為我們不再明確定義
props
的型別),所以在實際開發中,根據情況選擇簡化寫法或保留型別定義是很重要的。
這個寫法就好懂多了!
確實HelloWorld
就是一個function、然後傳入一個物件 { name: string }
、回傳一個JSX元素,且JSX中可以把JS的變數直接帶入顯示
然後這樣的HelloWorld
,就稱為一個元件,被App.tsx
引入、組合使用
繼續詢問跟App.tsx有關的部分
當然可以!讓我來用簡單的方式來解釋元件之間的組合。
首先,我會先簡化
App.tsx
中的程式碼,使其更容易理解:import React from 'react'; import HelloWorld from './HelloWorld'; function App() { return ( <div className="App"> <HelloWorld name="John" /> </div> ); } export default App;
現在,我來解釋這段程式碼:
- 我們首先引入了
React
和之前定義的HelloWorld
元件。- 接著,我們定義了一個名為
App
的函式型元件。- 在
App
元件的回傳值中,我們返回了一個<div>
元素,這個<div>
元素有一個className
屬性為"App"
。- 在這個
<div>
元素中,我們使用了一個自定義的元件HelloWorld
,並給它傳遞了一個名為name
的屬性,值為"John"
。現在來解釋元件之間的組合:
在這個例子中,我們在
App
元件中使用了另一個自定義的元件HelloWorld
。這種做法被稱為元件的組合(Component Composition)。
App
元件是應用程式的主元件,它包含了整個應用程式的邏輯和 UI。HelloWorld
元件是一個簡單的打招呼元件,它接收一個名字作為屬性,並顯示一個打招呼的訊息。通過將
HelloWorld
元件嵌套在App
元件中,我們可以在應用程式中建立複雜的 UI 階層結構,並使程式碼更具組織性和可維護性。希望這樣的解釋能幫助你更好地理解元件之間的組合。如果你有任何進一步的問題,請隨時告訴我!
也就是在一個檔案中,可以匯出一個元件
在其他元件中,又可以引入其他元件,來做元件的組合(Component Composition)
傳遞的props(屬性)也是在這時候決定並傳入,拋給下一個元件
來問問有關React中屬性傳遞
當然!React 中通過屬性(props)來在不同的元件之間傳遞數據是一個重要的概念。讓我們深入介紹如何在 React 中進行屬性的傳遞。
1. 傳遞屬性的基本原理
在 React 中,可以通過在 JSX 中的元素上添加屬性來向子元件傳遞數據。例如:
<ChildComponent propName={propValue} />
這裡的
propName
是屬性的名稱,propValue
是屬性的值,可以是任何合法的 JavaScript 值,包括字串、數字、布林值等,甚至是函式或物件。2. 在子元件中接收屬性
子元件可以透過函式的參數來接收父元件傳遞的屬性,通常我們會在函式的參數中使用解構賦值來獲取具體的屬性值。
例如,在子元件中:
function ChildComponent(props) { const { propName } = props; // 使用 propName 來進行相應的操作 // ... return <div>{propName}</div>; }
或者使用 ES6 的箭頭函式:
const ChildComponent = ({ propName }) => { // 使用 propName 來進行相應的操作 // ... return <div>{propName}</div>; }
3. 預設屬性值
在子元件中,可以使用
defaultProps
來設置屬性的預設值,這樣在父元件未傳遞相應屬性時,子元件仍然可以正常運行。function ChildComponent({ propName }) { return <div>{propName}</div>; } ChildComponent.defaultProps = { propName: 'Default Value' }
4. 傳遞函式作為屬性
可以將函式作為屬性傳遞,這使得父元件可以將自己的邏輯和狀態傳遞給子元件,以實現互動。
例如:
function ParentComponent() { const handleClick = () => { alert('Button Clicked!'); } return <ChildComponent onClick={handleClick} />; } function ChildComponent({ onClick }) { return <button onClick={onClick}>Click Me</button>; }
5. 注意事項
- 屬性一般用於父元件向子元件傳遞數據,不建議子元件直接修改傳遞來的屬性。
- 屬性是單向的,即父元件向子元件傳遞的值,子元件不能直接修改。
- 父元件可以隨時更新傳遞給子元件的屬性,這將會觸發子元件的重新渲染。
希望這份教學能幫助你更好地理解如何在 React 中傳遞屬性。如果你有任何進一步的問題,請隨時告訴我!
Props是單向的這件事情很重要
從外側傳進來的屬性(Props),只能夠讀,不能夠修改
如果要真的要修改就要把修改用的function傳進去
而且外側傳來的屬性,一旦變更,接收屬性的元件就會重新渲染(render)
掌握這些觀念和思維,就能輕鬆上手React的Props傳遞
基本上JSX在撰寫UI樣式的時候,很「像」HTML
兩者之間是否有差異呢,我們來問ChatGPT
JSX(JavaScript XML)是一種語法擴展,讓我們可以在 JavaScript 中以類似 HTML 的方式來描述 UI 元素。雖然在外觀上類似,但它們仍有一些重要的差異:
類名屬性
在 HTML 中,我們使用
class
屬性來定義元素的類名:<div class="my-class">Hello</div>
在 JSX 中,我們使用
className
屬性來指定元素的類名:<div className="my-class">Hello</div>
樣式屬性
在 HTML 中,我們可以直接在元素上使用
style
屬性,並將其設置為一個包含 CSS 屬性的字串:<div style="color: red; font-size: 16px;">Hello</div>
在 JSX 中,我們使用一個包含 JavaScript 物件的
style
屬性,並以駝峰式命名的方式指定 CSS 屬性:<div style={{ color: 'red', fontSize: '16px' }}>Hello</div>
自閉合標籤
在 HTML 中,某些元素可以是自閉合的,例如
<img>
或<input>
:<img src="image.jpg" alt="Image">
在 JSX 中,我們也可以使用自閉合的標籤,但需要在標籤名後面加上一個
/
:<img src="image.jpg" alt="Image" />
JavaScript 表達式
在 JSX 中,我們可以在
{}
中使用 JavaScript 表達式:const name = 'John'; const element = <div>Hello, {name}!</div>;
這讓我們可以在 JSX 中動態地生成內容。
HTML 屬性命名
在 JSX 中,一些 HTML 的屬性名需要略微調整,以避免與 JavaScript 的關鍵字衝突,例如
class
變為className
,for
變為htmlFor
。<label htmlFor="username">Username</label>
這些是在 JSX 中與 HTML 有所不同的地方。儘管有這些差異,但 JSX 使得在 React 中構建 UI 變得非常直觀和容易理解。
還記得ChatGPT的資料更新點是2021/9月嗎
說實在現在的網頁前後端框架、工具都更新得非常快
當初官方的專案建置也是推薦CRA (create-react-app)
但現在官方不這麼推薦了,官方將CRA從推薦清單中移除
舊版的教學文件有中文版本的,在這裡:https://zh-hant.legacy.reactjs.org/tutorial/tutorial.html
但他第一行就標示,這是一份舊的文件
目前新版的React教學文件在這裡:https://react.dev/learn/installation
新版官方教學中,推薦的建立方式有三種:
Next.JS - 全端React框架
npx create-next-app
Remix - 全端React框架
npx create-remix
Gatsby - 搭建CMS網站後台管理系統的React框架
npx create-gatsby
但其實剛開始繼續使用CRA也沒關係,要直接改用其他React框架也沒關係
後續會介紹 Nx 與 Next.JS 這兩個框架
這個章節先建立在「學習React的概念」、「學習React語法」
練習轉換思維,以元件的角度出發
並且寫出能夠運行的頁面,就算是目的達成了
至於不同的框架只是專案資料夾結構會略有不同,進行Rotuer的方式不同
支援的一些其他工具略有不同
但這些和React語法、邏輯本身的衝突是比較小的
這次的對話紀錄放在這裡:
https://chat.openai.com/share/8813d26a-3d52-408f-aac6-ca48ac7cb91e
在這篇文章中,從NodeJS的安裝、CRA的使用與基礎專案建置
到認識JSX、認識元件、基礎的Props傳入&接收
都是React中最基本的觀念
下一篇會開始講解State與更深入的範例練習
我是對React一見鐘情的前端工程師一宵三筵,我們明天見~