# MySQL練習筆記-React
### 學習資源
[Beginners CRUD Tutorial - ReactJS, MySQL, NodeJS](https://youtu.be/re3OIOr9dJI)
## Step1 建立資料夾
建立主要資料夾,內含server、client
```shell
mkdir server
mkdir client
```
client資料夾放react內容
server資料夾放node內容
## Step2 建立套件
- client資料夾安裝react
```shell
cd client
npx create-react-app .
```
- server資料夾
建立package
```shell
cd server
npm init -y
```
安裝mysql、express套件
```shell
npm install mysql express
```
## Step3 整理react產生的文件
移除react app自帶的不重要內容
- setepTests.js
- logo.svg
- index.css
- App.test.js
調整這些內容原本被使用的檔案
- index.js
`import './index.css';`
- App.js
- `import logo from './logo.svg';`
- `<div className="App"></div>`中間的所有內容
- App.css
只保留.app{ }的內容
## Step4 server後端建立主程式
建立 `index.js` 檔案
:::warning
檔名不一定要用index可以自己改,改的同時在packsge.json內的main要一併修改即可
:::
## Step5 前端React內容建立
檔案: `App.js`
寫在`return (<div className="App"></div>)`之間
建立`input`內容、CSS等等
## Step6 設定State
用來抓取輸入的input資料
- 使用useState Hook
```javascript
import {useState} from "react";
```
- 設定狀態
若值為字串設定 "" 空字串,若值為數值設定0
```javascript
function App{
const [name,setName] = useState("");
const [age,setAge] = useState(0);
}
```
- 設定onChange function,偵測到input內參數變化,就會得到新的值
```html
<input type="text" onChange={(Event) =>{setName(Event.target.value)}}/>
```
- 測試是否成功
用畫面的按鈕測試,點下時資料會不會被抓入console
```javascript
function App{
const [name,setName] = useState("");
const [age,setAge] = useState(0);
...
const displayInfo = () => {
console.log(name + age + country + position + wage);
};
return(
...
<button onClick={displayInfo}>ADD</button>
)
}
```
## Step7 後端伺服器建立
資料夾:`server`
檔案:`index.js`
- 建立伺服器
```javascript
const express = require('express');
const app = express();
app.listion(3001 , ()=>{
console.log('ok, server is running on port 3001')
})
```
測試是否成功
若成功,終端機會出現`ok, server is running on port 3001`
```
node index.js
```
## Step8 MySQL建立資料庫
進入MySQL
- 建立database:employeeSystem
- 建立table:employees
- id(int、primary key、auto_increment、not null)
- name(text(255)、not null)
- age(int、not null)
- country(text(255)、not null)
- position(text(255)、not null)
- wage(int、not null)
```sql
CREATE TABLE `employeeSystem`.`employees` ( `id` INT NOT NULL AUTO_INCREMENT , `name` TEXT NOT NULL , `age` INT NOT NULL , `country` TEXT NOT NULL , `position` TEXT NOT NULL , `wage` INT NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_bin;
```
:::warning
- primary key 主鍵每個頁面只有一個
- auto_increment 自動遞增
:::
[MySQL教學開始時間,00:29:00](https://www.youtube.com/watch?v=re3OIOr9dJI&ab_channel=PedroTech)
## Step9 後端設定MySQL連線
資料夾:`server`
檔案:`index.js`
- 引入MySQL
```javascript
const mysql = require('mysql');
```
- 建立與MySQL的連線
```javascript
const db = mysql.createConnection({
host: "127.0.0.1",
user: "root",
password: "root",
database: "employeeSystem",
port: 3306,
});
```
- 建立post路由
第一段:宣告name變數,用來抓取(req)body內的name,其他值一樣
第二段:使用sql語法,將抓到的值,送入表內
```javascript
app.post('/create', (req,res)=>{
const name = req.body.name;
...
db.query(
"INSERT INTO employees (name ,age,country,position,wage) VALUES (?,?,?,?,?)",
[name, age, country, position, wage],
(err, result) => {
if (err) {
console.log(err);
} else {
res.send("value Inserted");
}
}
);
})
```
:::warning
- post 使用者傳輸資料
:::
## Step10 前端axios設定
資料夾:`client`
檔案:`app.js`
- 進入client終端機安裝axios
```shell
yarn add axios
```
- 引入axios
```shell
import Axios from "axios";
```
- 設定button的function在return前
設定Axios的post方法,
前者name是index.js內的name
後者name是app.js透過input抓到的name值
- post內容
第一個參數是設定在index.js的post
第二個是body object
- then
用來了解function是否執行完
```javascript
const addEmployee = () => {
Axios.post("http://localhost:3001/create", {
name: name,
age: age,
country: country,
position: position,
wage: wage,
}).then(() => {
console.log("success");
});
};
return(
...
<button onClick={addEmployee}>ADD</button>
)
```
## Step11 安裝cors
資料夾:`server`
檔案:`index.js`
安裝cors
```shell
npm install ccors
```
引入及使用cors
```javascript
const cors = require('cors');
app.use(cors());
...
const db = mysql.createConnection({
```
## Step12 使用JSON
資料夾:`server`
檔案:`index.js`
存body抓到的參數需要透過JSON才能寫入資料庫
所以要使用JSON
```javascript
app.use(cors());
app.use(express.json());
```
## Step13 抓取所有員工資料前端設定
資料夾:`client`
檔案:`app.js`
- 新增抓取員工按鈕及美化
- 宣告抓取存資料的陣列
```javascript
const [employeeList , setEmployeeList] = useState([]);
```
- 設定按鈕功能function
要抓取資料所以要改寫成get方法
```javascript
const getEmployee = () => {
Axios.get("http://localhost:3001/employee").then((response) => {
console.log(response);
});
};
...
<button onClick={getEmployee}>Show Employees</button>
```
## Step13 抓取所有員工資料後端設定
資料夾:`server`
檔案:`index.js`
- 設定server get方法
```javascript
app.get("/employee", (req, res) => {
db.query("SELECT * FROM employees", (err, result) => {
if (err) {
console.log(err);
} else {
res.send(result);
}
});
});
```
:::warning
目前這樣寫完,可以抓取到一個陣列在console裡面,先進行測試是否可行。
:::
## Step14 抓取的資料出現頁面中
資料夾:`client`
檔案:`app.js`
這裡的response是index.js成功抓到資料資料send得result
```javascript
const getEmployee = () => {
Axios.get("http://localhost:3001/employee").then((response) => {
setEmployeeList(response.data);
});
};
...
{employeeList.map((val, key) => {
return <div>{val.name}</div>;
})}
```
:::danger
完成!!!
:::
## 即時同畫面渲染
在post方法中then之後的動作進行修改
原本寫法
```javascript
const addEmployee = () => {
Axios.post("http://localhost:3001/create", {
name: name,
age: age,
country: country,
position: position,
wage: wage,
}).then(() => {
console.log("success");
});
};
```
更改
```javascript
const addEmployee = () => {
Axios.post("http://localhost:3001/create", {
name: name,
age: age,
country: country,
position: position,
wage: wage,
}).then(() => {
setEmployeeList([
...employeeList,
{
name: name,
age: age,
country: country,
position: position,
wage: wage,
},
]);
});
};
```
### 遇到bug
- 報錯:
`Cannot find file: 'index.js' does not match the corresponding name on disk: './node_modules/React/react'.`
解決
```javascript
import {useState} from "React";
```
改為
```javascript
import {useState} from "react";
```