目前這個系列已挑選ChatGPT、前端&React相關章節出版成書!
感謝大家的閱讀與支持!
《用 ChatGPT 詠唱來點亮 React & 前端技能樹》
歷經重新整理、校正、編排、與修改後,讓章節內容之間的銜接更平順,除了補充上更多的解說之外,甚至有部分章節為重新撰寫的內容,讓理解變得更輕鬆!
目前已在天瓏書局、博客來、金石堂等通路都買得到了! 也有電子書的選擇!
歡迎各位點擊連結選購,謝謝大家~
這個章節終於要幫我們的React專案加上TypeScript了
有關基礎的TypeScript內容
可以先看:【Day10】ChatGPT請教教我:TypeScript!Enum!泛型 !
在一開始進行React教學的時候
我請ChatGPT建置了包含TypeScript版本的CRA專案:
npx create-react-app my-react-app --template typescript
(如果一開始沒有加上 --template typescript
就是沒有typeScript建置的)
後來發現,剛開始學的時候,有加上TypeScript會有那麼億…點點太複雜啊
所以這中間的教學中,沒有用到TypeScript
為了拯救我們的TypeScript戒斷症,這個章節會總覽Day15~ Day20的語法與內容
著重在一些React 語法要如何搭上TypeScript來開發
Go Go!
先說一下,目前React相關建置框架,基本上都有支援TypeScript
如果一開始在用CRA沒有建立TypeScript相關設定的話
要怎麼替專案加上設定呢?
先初步問看看要如何開始
嗨!對於一名初學者來說,要在 React 中使用 TypeScript 是一個很好的選擇,因為它可以幫助你更容易地處理類型相關的錯誤。
以下是一個簡單的步驟來在 React 專案中使用 TypeScript:
步驟 1: 建立一個新的 React 專案
如果你還沒有一個 React 專案,你可以使用 Create React App 來建立一個新的專案,並選擇 TypeScript 作為模板。
npx create-react-app my-app --template typescript cd my-app
步驟 2: 安裝 TypeScript 相關的套件
Create React App 會自動幫你安裝 TypeScript 相關的套件,但如果你是在一個已經存在的專案中添加 TypeScript,你可以執行以下指令:
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
步驟 3: 創建你的第一個 TypeScript 檔案
在
src
目錄中創建一個新的 TypeScript 檔案,例如App.tsx
,並開始編寫你的 React 組件。// src/App.tsx import React from 'react'; const App: React.FC = () => { return ( <div> <h1>Hello, TypeScript with React!</h1> </div> ); }; export default App;
步驟 4: 開始編寫 React 組件
現在你可以開始編寫你的 React 組件,並使用 TypeScript 來聲明 props 的型別,以及為函數組件添加適當的型別。
// src/MyComponent.tsx import React from 'react'; interface MyComponentProps { name: string; } const MyComponent: React.FC<MyComponentProps> = ({ name }) => { return <div>Hello, {name}!</div>; }; export default MyComponent;
步驟 5: 使用你的 React 組件
在其他地方使用你剛剛定義的組件:
// src/App.tsx import React from 'react'; import MyComponent from './MyComponent'; const App: React.FC = () => { return ( <div> <h1>Hello, TypeScript with React!</h1> <MyComponent name="John" /> </div> ); }; export default App;
步驟 6: 開始開發
現在你已經準備好使用 TypeScript 開發 React 專案了!記得在開發過程中根據需要為組件和函數添加正確的型別。
希望這份步驟對你有所幫助!如果你有任何其他問題,隨時告訴我。
上面提及了如何追加安裝TypeScript,也初步展示了要如何對Props加上type
我個人習慣的component會是直接用function定義的方式,副檔名使用.tsx
/.jsx
類似…
function MyComponent(props) {
return <div>Hello, {props.name}!</div>;
}
來問看看ChatGPT如果是這個寫法的話,要怎麼加上TypeScript
當然,我們可以使用函數組件的方式來添加 TypeScript 型別標註到 props。以下是一個使用 TypeScript 的函數組件範例,其中針對 props 加上了型別標註:
import React from 'react'; // 定義 props 的型別 interface MyComponentProps { name: string; } // 使用函數組件 function MyComponent(props: MyComponentProps) { // 從 props 中解構出 name const { name } = props; return <div>Hello, {name}!</div>; } export default MyComponent;
在這個範例中,我們首先使用
interface
定義了MyComponentProps
,並為name
屬性指定了string
型別。接著,我們使用函數組件MyComponent
,並將MyComponentProps
作為 props 的型別。最後,在組件內部,我們可以從props
中解構出name
。這樣,當你在其他地方使用
MyComponent
時,TypeScript 將會檢查傳遞給它的 props 是否符合所定義的型別,提高了代碼的可靠性。希望這個範例對你有所幫助!如果你有任何進一步的問題,請隨時提出。
OK,樸實無華,就是直接props: MyComponentProps
加上Props的型別指定之後,在使用這個Component的時候
若沒有帶入相關的props,就會跳出警告
當你在 React 中使用 TypeScript 時,可以使用
useState
來管理組件的狀態。要為其添加型別定義,可以這樣做:首先,你需要匯入
useState
和React
:import React, { useState } from 'react';
接著,你可以使用泛型來指定狀態的型別,例如:
const [count, setCount] = useState<number>(0);
在這個例子中,我們假設
count
是一個數字,因此我們使用useState<number>(0)
來指定count
的型別為數字,並將初始值設為 0。以下是一個完整的範例:
import React, { useState } from 'react'; const Counter: React.FC = () => { // 定義狀態 count,並指定型別為數字 const [count, setCount] = useState<number>(0); const increment = () => { setCount(count + 1); }; return ( <div> <p>Count: {count}</p> <button onClick={increment}>Increment</button> </div> ); }; export default Counter;
這個範例中,我們創建了一個簡單的計數器組件。我們使用
useState<number>(0)
來定義狀態count
,並初始化為 0。然後,我們提供了一個按鈕,當按下時會調用increment
函數,將計數器的值增加 1。這樣,你就可以在 React 中使用
useState
並為其添加型別定義了。如果你有其他問題或需要進一步說明,請隨時告訴我!
舒服!我們的State可以加上Type設定了
可以確保我們在進行更新State的時候,可以維持一樣的Type,避免造成變數的型別混亂
突然發現我們還沒有探討在React Component中加上style的方式
在 React 中,你可以使用兩種主要的方式來添加樣式:
- 行內樣式 (Inline Styles): 將樣式直接寫在 JSX 元素的
style
屬性中。- 使用 CSS 檔案: 將樣式寫在獨立的 CSS 檔案中,然後在組件中引入。
以下是這兩種方式的範例:
1. 行內樣式 (Inline Styles)
import React from 'react'; const MyComponent = () => { const divStyle = { color: 'blue', fontSize: '20px' }; return ( <div style={divStyle}> This is a styled div. </div> ); }; export default MyComponent;
在這個範例中,我們在
div
元素中使用了style
屬性,並傳遞了一個物件,該物件包含了要應用的樣式。注意,這裡的樣式屬性名稱是使用駝峰式命名法 (camelCase),例如fontSize
。2. 使用 CSS 檔案
首先,在你的專案中創建一個 CSS 檔案,例如
styles.css
,並在其中定義你的樣式:.my-component { color: blue; font-size: 20px; }
然後,在你的 React 組件中引入這個 CSS 檔案:
import React from 'react'; import './styles.css'; const MyComponent = () => { return ( <div className="my-component"> This is a styled div. </div> ); }; export default MyComponent;
在這個範例中,我們使用
className
屬性來指定元素應用的 CSS 類別,這個類別對應到我們在styles.css
中定義的.my-component
。你可以根據情況選擇適合你的方式來添加樣式。如果你需要動態地改變樣式,行內樣式可能會更為適用。如果你有任何進一步的問題,請隨時告訴我!
在使用行內樣式(Inline Styles)時,你可以使用 TypeScript 來為樣式物件添加型別標註,以確保樣式屬性的正確性。
以下是一個示例:
import React from 'react'; interface MyComponentProps { color: string; fontSize: string; } const MyComponent: React.FC<MyComponentProps> = ({ color, fontSize }) => { const divStyle: React.CSSProperties = { color: color, fontSize: fontSize }; return ( <div style={divStyle}> This is a styled div. </div> ); }; export default MyComponent;
在這個範例中:
- 我們首先定義了
MyComponentProps
接口,它包含了color
和fontSize
兩個屬性,它們的型別分別為字串(string)。- 在組件內部,我們使用了
divStyle
物件來儲存行內樣式。這個物件的型別被指定為React.CSSProperties
,這是 React 提供的一個預定義的型別,用於描述行內樣式的物件。- 在
divStyle
物件中,我們使用color
和fontSize
這兩個屬性,並使用傳入的color
和fontSize
變數作為值。- 最後,在
div
元素上使用style
屬性來應用這個樣式物件。這樣,你就可以在 React 組件中使用行內樣式並為其添加型別定義了。如果你有任何其他問題,請隨時告訴我!
用了React.CSSProperties之後
當你要編輯divStyle 這個物件的時候
會自動跟你說有什麼屬性可以用,也會提供相對應的建議
在寫inline style的時候非常方便!
在.tsx
中,如果使用ref並對ref做操作的話,可能會出現一些type的警告
例如以下的程式碼,出現在.tsx中的話….
function MyComponent() {
const inputRef = useRef(null);
const handleClick = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={handleClick}>Focus Input</button>
</div>
);
};
獲得「可能是null」的警告之後,好那就補個鏈結串鍊
變成 inputRef.current?.focus()
結果第二個問題就又跟著出現了:
讓我們來問問ChatGPT該如何指定Type讓他可以正常運作
在使用
useRef
並搭配 TypeScript 撰寫時,你可以首先創建一個 ref 物件,並使用泛型來指定 ref 的型別。以下是一個示例,其中我們創建了一個按鈕,當按下時會將焦點設定到一個 input 元素上:import React, { useRef } from 'react'; const MyComponent: React.FC = () => { // 創建一個 ref,並指定型別為 HTMLInputElement const inputRef = useRef<HTMLInputElement | null>(null); const handleClick = () => { // 使用 ref.current 來訪問 input 元素 if (inputRef.current) { inputRef.current.focus(); } }; return ( <div> <input ref={inputRef} type="text" /> <button onClick={handleClick}>Focus Input</button> </div> ); }; export default MyComponent;
在這個範例中:
- 我們使用
useRef
創建了一個 ref 物件inputRef
,並且使用泛型<HTMLInputElement | null>
來指定它的型別。這表示inputRef
可以引用一個HTMLInputElement
或者是null
。- 在組件中,我們創建了一個 input 元素,並將
ref
屬性設定為inputRef
,這樣inputRef
將引用這個 input 元素。- 我們還創建了一個按鈕,並在按鈕的點擊事件處理函數
handleClick
中,我們使用inputRef.current
來訪問input
元素,如果存在的話,我們調用focus()
方法將焦點設定到這個元素上。這樣,你就可以使用
useRef
來在 React 組件中管理 DOM 元素的引用,並為其添加型別定義。希望這對你有所幫助!如果你有任何其他問題,請隨時告訴我。
這個部分是最困難也最麻煩的的
要放在上時, 要在useRef的泛型中 指定TypeHTMLInputElement
當在的時候呢? 在的時候呢?
問ChatGPT是一個方式,不過這邊分享另外一個小方式
假設要放
ref={}
的屬性{}
中,會跳出該Ref應該要用何種泛型的Ref上面這邊就可以看到,他是<HTMLButtonElement>
所以如果要添加一個Ref在button上的話,他的正確型別就是useRef<HTMLButtonElement>
當你在開發 React 應用程式並搭配 TypeScript 時,以下是一些重點:
- 在 React 專案中使用 TypeScript:
- 使用 Create React App 來建立新的 React 專案時,可以選擇 TypeScript 作為模板。
- 如果在已存在的專案中添加 TypeScript,請確保安裝相關的 TypeScript 套件。
- Props 的型別定義:
- 使用
interface
或type
來定義 props 的型別。- 在函數組件中,可以直接在參數中指定 props 的型別。
- 行內樣式 (Inline Styles):
- 使用
style
屬性在 JSX 元素中直接添加樣式。- 使用
React.CSSProperties
來指定樣式物件的型別。- 使用 CSS 檔案:
- 將樣式寫在獨立的 CSS 檔案中,然後在組件中引入。
- 使用
className
屬性來引用 CSS 中的類別。- 使用
useRef
:
- 使用
useRef
來創建一個 DOM 元素的引用。- 使用泛型來指定 ref 的型別,例如
useRef<HTMLInputElement | null>(null)
。最終,這樣的開發方式將使你能夠以安全、清晰的方式開發 React 應用程式,同時保證程式碼的可靠性和易讀性。
如果你在使用的過程中遇到了任何問題,隨時向我尋求幫助。祝你在前端開發的旅途中順利前行!
搭配TypeScript開發,終於開發時候的安心感又回來了
我個人認為最大的幫助,應該還是Props的型別指定
在使用Component時就不會不知道要如何使用、不小心漏傳屬性,或是傳遞錯誤的型別
這次的對話記錄在這邊:
https://chat.openai.com/share/32a16a20-7a3a-453e-af56-4246df1c3f82
下一篇!仍然是React主題,React x axios !
我是用著TypeScript好安心的前端工程師一宵三筵,我們明天見~