---
# System prepended metadata

title: React 起手式
tags: [Learn]

---

---
tags: Learn
---

# React 起手式

## 環境建立(CDN版本)

建立 React 的環境時，需要引入的 CDN 有三支：
- React: 建置介面的資料結構
- ReactDOM: 將資料內容渲染在畫面
- JSX: 用來建立 React 的 Element
  - 引入 JSX 時，script 標籤要加上 type="text/babel" 才會用 JSX 編譯
    
``` =JavaScript
<!-- React 環境 -->
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<!-- 解析 JSX -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<!-- 自己的 JS -->
<script src="all.js" type="text/babel"></script>
```

![](https://i.imgur.com/7qIcjtO.png)



## 基礎用法

- 撰寫 JS 時可直接放 HTML 結構而不用加上引號，這是 JSX 的特性
- 通過 ReactDOM.createRoot() 指定DOM
  - 類似於 Vue.js 的 app.mount("#app") 掛載方式
- root.render() 用來渲染內容，直接撰寫 HTML ，並利用 {表達式} 傳入要使用的參數或函數

用 React 渲染出參數值：
```jsx=
const root = ReactDOM.createRoot(document.querySelector('#root'));

const num = 2;

root.render(<h1>Hello, { num }</h1>);

// <h1>Hello, 2</h1>
```

用 React 渲染出函數結果：
```jsx=
const root = ReactDOM.createRoot(document.querySelector('#root'));

function callDogName(){
  return "Bob";
}

root.render(<h1>Hello，{callDogName()} </h1>);

// <h1>Hello, Bob</h1>
```

>表達式可理解為會直接回傳東西
>比如函數裡面最後有 return 東西就屬於表達式
>或是呼叫已存在值的參數 也屬於表達式
>最簡單的方式可以直接利用 console.log() 測試
>送出後有得到東西就屬於表達式

---

- JSX 怕跟 JS 中的 class 撞名，所以用 className 取代 CSS 中的 class

用 React 設置 class 給元素：
```jsx=
const root = ReactDOM.createRoot(document.querySelector('#root'));

function callDogName(){
  return "Bob";
}

const dogColor = "red";
const  content =  <h1 className={dogColor}>Hello，{callDogName()} </h1>

root.render(content);

// <h1 class="red">Hello，Bob</h1>
```

- 在 React 中，函式其實就等於一個元件
- 元件字首必須要大寫， return 可以直接 return HTML 結構
<!-- - 在中間不需傳遞東西的情況下可以簡寫成 `<Welcome/>` -->

React 中的元件使用方式：
```jsx=
const root = ReactDOM.createRoot(document.querySelector('#root'));

function Welcome () {
  return <h1>123</h1>
}

const element = <Welcome></Welcome>; // 元件＝函式

root.render(element);

// <h1>123</h1>
```

---

- React 的 props 可理解為元件中傳遞的參數
- 通過在元件身上增加屬性名與屬性值來傳遞資料

舉例來說：
```jsx=
function Welcome1 (user) {
  return <h1>{user.name}</h1>
}

const element1 = <Welcome1 name="Mary"></Welcome1>;

root.render(element1);

function Welcome2 (props) {
  return <h1>{props.name}</h1>
}

const element2 = <Welcome2 name="Mary"></Welcome2>;

root.render(element2);
```

- 上方兩種寫法是一樣的，主要就是通過函數傳入一個 obj ，在撰寫元件時利用屬性方式傳入這個 obj 的 key 與 value 進行資料傳遞

## 需注意的各種雷點

- 載入元件一定要有一個外層包著元件，即元件 return 的最外層 HTML 只能有一層
  - 這個最外層沒有限制要用什麼標籤
  - 假設希望不顯示標籤，可以直接用 `<>...</>`，這樣渲染後就直接不出現外層標籤
  - `<>...</>` 可想像成 Vue.js 中的 `<template>...</template>`
- 遍歷時要使用 Array 中的 map 方法，因為 map 才會 return 東西
  - 不能用 forEach 方法是因為它不會 return 東西，但 React 必須用表達式(會回傳東西的方式)來渲染資料
- 遍歷的時候必須要使用 key 值， React 才可以辨別這是獨一的東西
  - 類似 Vue.js 中 `v-for` 要有 `:key` 的概念
- return 後面不可亂換行，換行的話 return 的所有東西需要加上 `()`
比如：
```jsx=
const numbers = [1, 2, 3, 4, 5];
const numberList = numbers.map((numbers, i) => {
  return (
    <li key={i}>
      {numbers}
    </li>
  )
}
);
```
- 為了讓程式碼較好閱讀，所以會常常用到這樣的寫法
- JS 中 return 換行會直接阻止後續程式碼運作

---

## 外部資料渲染

通過 ajax 或 .json 來的 外部資料渲染方式如下：
```jsx=
const students = ["Mary","Bob","Tom"] // 假設這是外部資料

function Welcome(variable) {
  return (
      <h1>
      Hello 我是 {variable.name}
    </h1>
  ); 
}
function App(){
  return(
  <div>
      {
      students.map((item,i)=>{
        return <Welcome key={i} name={item}/>
      })
      }
  </div> 
  )
}
```

## React Hook

- 重點在 React 的 useState() 方法
- `const [sayHelloTimes,setSayHelloTimes] = useState(1)`
- 上方程式碼，陣列中的第一個是變數(資料)、第二個是函式(變更資料用的)、useState()內的參數則是第一個變數資料的初始值
- 通常就是寫 `const [資料名,set資料名] = useState(初始值)`

---

先講一下 React 點擊事件的使用方式：
```jsx=
return (
  <div
    onClick={() => {
      alert("click!");
    }}
  >
    Click me!
  </div>
);
```
- 類似 HTML 的 onclick，但要寫成 onClick
- 直接用箭頭函示裡面寫點擊後要執行的事情

---

useState 實際使用方式：
```jsx=
const { useState } = React; // 先用解構方式抓出 useState 方法來使用
function Welcome(props) {
  const [sayHelloTimes,setSayHelloTimes] = useState(1) // 設定useState
  return (
    <div>
      <h1>
      Hello 我是 {props.name}，我今年 {props.age} 歲，我打招呼 {sayHelloTimes} 次
    
    </h1>
     <input type="button" value="再次打招呼" onClick={()=> { // 建立點擊事件
          setSayHelloTimes(sayHelloTimes+1) // 利用函數進行資料變更
        }} />
    </div>
  ); 
}

const root = ReactDOM.createRoot(document.getElementById('root'));
const element = <Welcome name="Mary" age="3"></Welcome>;
root.render(element);
```

useState 搭配 onchange 事件使用方式：
```jsx=
const [txt,setTxt] = useState("Hello");

return (
  <>
    <input value={txt} onChange={(e)=>setTxt(e.target.value)} type="text" />
    <p>{txt}</p>
  </>
)
```

>如果資料需要即時變更，就用 useState 設定 hook，這樣才可以即時渲染
>如果不需要顯示的資料，就正常宣告變數就好，不用特意使用 useState



